1. 程式人生 > >Android如何用json格式傳資料到後臺(SSM) 做一個簡單的登入流程

Android如何用json格式傳資料到後臺(SSM) 做一個簡單的登入流程

哈嘍!剛剛開始接觸Android, 有很多地方都不同懂,甚至有點想放棄,曾幾何時,我會感嘆抓狂 安卓“從介面到放棄”,但做什麼事都要堅持下來奮鬥,這個登入做了一週了大哭,下面開始進入主題微笑

這篇部落格是寫Android 客戶端登入,怎樣傳資料到服務端(用的是SSM框架)。然後又從服務端查詢到資料,怎樣傳到Android端。  看到評論都要後臺程式碼,我放上了Git ,要的自取 服務端下載地址

     環境準備: 1 Android端:Android Studio 2.3.3 版本  

                     

              需要重要jar fastjson 和 gson  包下載地址:

點選開啟連結

              2,服務端:工具:  Eclipse 

               框架:spring+springmvc+mybatis  ,不會搭這個框架的私我,後期我會寫這個框架怎麼搭建的

             

           重要jar包:jackson.jar   下載地址:點選開啟連結

  1. Android 端
  1. 登入介面的 activity_login.xml檔案 ,我只貼了主要的控制元件的
  <LinearLayout
            android:id="@+id/email_login_form"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:orientation="vertical">

            <TextView
                android:layout_width="0dp"
                android:layout_height="0dp"
                android:id="@+id/userId"
                />

            <android.support.design.widget.TextInputLayout
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                >

                <EditText
                    android:id="@+id/username"
                    android:layout_width="match_parent"
                    android:layout_height="40dp"
                    android:hint="賬號"
                    android:inputType="textEmailAddress"
                    android:maxLines="1"
                    android:imeOptions="actionDone"
                    />
            </android.support.design.widget.TextInputLayout>

            <android.support.design.widget.TextInputLayout
                android:layout_width="match_parent"
                android:layout_height="wrap_content">

                <EditText
                    android:id="@+id/password"
                    android:layout_width="match_parent"
                    android:layout_height="wrap_content"
                    android:hint="密碼"
                    android:imeActionId="@+id/login"
                    android:imeActionLabel="@string/action_sign_in_short"
                    android:inputType="textPassword"
                    android:maxLines="1"
                    android:imeOptions="actionDone"
                     />
            </android.support.design.widget.TextInputLayout>

            <Button
                android:id="@+id/btn_login"
                style="?android:textAppearanceSmall"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:layout_marginTop="16dp"
                android:background="@color/colorloginbtn"
                android:text="登       錄"
                android:textColor="@color/bg_white"
                android:textStyle="bold"
                android:textSize="20sp" />


            <RelativeLayout
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:layout_marginTop="8dp">

                <Button
                    android:id="@+id/btnRegister"
                    android:layout_width="50dp"
                    android:layout_height="25dp"
                    android:text="註冊"
                    android:textSize="18sp"
                    android:background="@drawable/login_btn_click_bg" />

                <Button
                    android:id="@+id/btnForgotPassword"
                    android:layout_width="80dp"
                    android:layout_height="25dp"
                    android:layout_alignParentRight="true"
                    android:text="忘記密碼"
                    android:textSize="18sp"
                    android:background="@drawable/login_btn_click_bg" />
            </RelativeLayout>

        </LinearLayout>
    2.   LoginActib       
package com.gx.cn.hospitalmanage;

import android.content.Intent;
import android.os.Handler;
import android.os.Message;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.EditText;
import android.widget.TextView;
import android.widget.Toast;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONException;
import com.alibaba.fastjson.JSONObject;
import com.google.gson.Gson;
import com.gx.cn.hospitalmanage.MyFragmentOne.NetUtils;
import com.gx.cn.hospitalmanage.MyFragmentOne.User;
import com.loopj.android.http.AsyncHttpClient;
import com.loopj.android.http.AsyncHttpResponseHandler;
import com.loopj.android.http.RequestParams;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.net.HttpURLConnection;
import java.net.URL;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.HashMap;

import java.util.Iterator;
import java.util.Map;
import cz.msebera.android.httpclient.Header;

/**
 * A login screen that offers login via email/password.
 */
public class LoginActivity extends AppCompatActivity  {

    private Button btnRegister,btnForgotPassword,mEmailSignInButton;

    private Intent intent;
    private TextView userID;
    private TextView userName;
    private TextView password;

    private  String result;

    String name,pwd;  //定義使用者名稱和密碼

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_login);

        //隱藏標題
        getSupportActionBar().hide();

        //進入主介面
        mEmailSignInButton = (Button) findViewById(R.id.btn_login);
        mEmailSignInButton.setOnClickListener(new OnClickListener() {
            @Override
            public void onClick(View view) {
                EditText tvname=(EditText) findViewById(R.id.username); //獲取使用者控制元件
                  name= tvname.getText().toString(); //獲取控制元件裡面的值
                EditText tvPsd=(EditText) findViewById(R.id.password);
                 pwd=tvPsd.getText().toString();

                new Thread() {
                    @Override
                    public void run() {
                         int num= init(name,pwd);
                        if(num>0){   //判斷id是否大於1,>1就是查詢到有資料 ,可以進入主介面
                            Intent it=new Intent(LoginActivity.this,MainActivity.class);
                            it.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_SINGLE_TOP);
                            startActivity(it);
                        }else {
                            Toast.makeText (getApplicationContext(),"使用者或密碼錯誤", Toast.LENGTH_LONG ).show();
                        }
                    }
                }.start();
            }
        });

         //註冊
        btnRegister=(Button)findViewById(R.id.btnRegister);
        btnRegister.setOnClickListener(new OnClickListener() {
            @Override
            public void onClick(View v) {
                Intent it=new Intent(LoginActivity.this,RegisterActivity.class);
                startActivity(it);
            }
        });

      //忘記密碼
        btnForgotPassword =(Button)findViewById(R.id.btnForgotPassword);
        btnForgotPassword.setOnClickListener(new OnClickListener() {
            @Override
            public void onClick(View v) {

            }
        });

     }


     //json格式與服務端互動
     private int init(String name,String pwd){
//  192.168.3.138 這個ip地址是電腦Ipv4 地址 /20170112 是服務端的專案名稱  /login/toJsonMain 是@RequestMapping的地址
          String urlPath="http://192.168.3.138:8080/20170112/login/toJsonMain.action";
    //    String urlPath="http://192.168.42.207:8080/20170112/login/toJsonMain.action"; 這個是實體機(手機)的埠
         URL url;
         int id=0;
         try {
              url=new URL(urlPath);
             JSONObject jsonObject=new JSONObject();
             jsonObject.put("username",name);  //引數put到json串裡
             jsonObject.put("password",pwd);

             //JSONObject Authorization =new JSONObject();
          //   Authorization.put("po類名",jsonObject 即po的欄位)

             String content=String.valueOf(jsonObject);  //json串轉string型別

             HttpURLConnection conn=(HttpURLConnection) url.openConnection(); //開啟連線
             conn.setConnectTimeout(5000);

             conn.setDoOutput(true);
             conn.setRequestMethod("POST");
             conn.setRequestProperty("ser-Agent", "Fiddler");
             conn.setRequestProperty("Content-Type","application/json");
            //寫輸出流,將要轉的引數寫入流裡
             OutputStream os=conn.getOutputStream();
             os.write(content.getBytes()); //字串寫進二進流
             os.close();

             int code=conn.getResponseCode();
             if(code==200){   //與後臺互動成功返回 200
                 //讀取返回的json資料
                 InputStream inputStream=conn.getInputStream();
                 // 呼叫自己寫的NetUtils() 將流轉成string型別
                 String json= NetUtils.readString(inputStream);

                 Gson gson=new Gson();  //引用谷歌的json包
                 User user=gson.fromJson(json,User.class); //谷歌的解析json的方法

                 id =user.getId();  //然後user.get你想要的值
                 String username=user.getUsername();
                 String password=user.getPassword();

             }else{
                 Toast.makeText (getApplicationContext(),"資料提交失敗", Toast.LENGTH_LONG ).show();
             }

         }catch (Exception e){
             e.printStackTrace();
         }
         return  id;
     }

     
}
 3. NetUtils 這個類是 將流轉成string型別,LoginActivity會呼叫到     
public class NetUtils {

    public static byte[] readBytes(InputStream is){
        try {
            byte[] buffer = new byte[1024];
            int len = -1 ;
            ByteArrayOutputStream baos = new ByteArrayOutputStream();
            while((len = is.read(buffer)) != -1){
                baos.write(buffer, 0, len);
            }
            baos.close();
            return baos.toByteArray();
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null ;
    }
    public static String readString(InputStream is){

        return new String(readBytes(is));
    }

}
   4. 實體類: User   
public class User {

    private int id;
    private String username;
    private String password;

    public int getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }

    public String getUsername() {
        return username;
    }

    public void setUsername(String username) {
        this.username = username;
    }

    public String getPassword() {
        return password;
    }

    public void setPassword(String password) {
        this.password = password;
    }

}
生成get和set() ,快捷鍵 Alt+Insert
5.  在AndroidManifest.xml  裡面加上  
<uses-permission android:name="android.permission.INTERNET"/>
 開啟Android連線網路6. 斷點調式:看圖      第一次執行要斷點測試:主要看content 這個值後面有沒有生成資料,或者生成的格式是否和我圈的一致,如果不是這樣的json格式,Android 傳送的請求可能會失敗,或者JAVA服務端接收不到資料。 如果能傳送過去,後臺根據username和password這兩個引數查詢,如果查詢到資料就返回 json =後面這一串json資料, 如果查詢不到,json=“ ”空   服務端:(SSM) 1.  Controller層 處理請求    
package cn.itcast.ssm.controller;


import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import cn.itcast.ssm.po.UserCustom;
import cn.itcast.ssm.service.UserService;

@Controller
@RequestMapping("/login")
public class LoginJsonTest {
	
	@Autowired
	private UserService userService; //注入UserService
		
	//獲取key/value格式 從jsp頁面傳也可以,從Android傳來也可以,只要格式對應這裡接收就行了
	@RequestMapping("/toMain")
	public @ResponseBody UserCustom toMain(UserCustom  userCustom ) throws Exception{
			
		UserCustom userList  =userService.selectUserIf(userCustom);   		 
		return userList;		
	}
	
	//獲取json格式 從Android端傳來的json格式,如果不是json格式,這裡就接收不到資料
	@RequestMapping("/toJsonMain")
	public @ResponseBody UserCustom toJsonMain(@RequestBody UserCustom  userCustom ) throws Exception{
			
		UserCustom userList  =userService.selectUserIf(userCustom);  //查詢語句	 
		return userList;   //返回json格式的資料給Android ,這裡為什麼這簡單,都是Jackson.jar做的工作			 
	}
	
}
2.如果Android端 哪個邊沒有問題,請求就能響應 後臺 記得斷點測試,看圖吧

3.查詢到資料併成功返回 ,看圖吧

jsp 頁面傳到json資料:

  總結一下: 1.首先要做好Java後臺的工作,搭建好框架,用jsp頁面寫一個簡單登入介面,然後用將使用者名稱和密碼通過ajax() 傳送請求,記得ajax方法裡面用json格式,傳遞引數,如果能傳到後臺,你就成功一半了,然後返回json資料就很簡單了,因為jsp頁面解析json資料相對比Android簡單得多,然後按照這個思路去跟Android端連線,記得把這個連線地址複製到Android端請求的url地址2.在Android端,我剛開始是不會將引數轉json格式,和將json資料轉成我們想要的資料型別,都是搞上網查詢,看大神們怎樣用json的,不懂就要多問,多查詢資料。3.如果上面程式碼中有什麼不對的地方,請各位大神指點一下,或者大家有什麼想說都可以,大家共同學習,一起進步。