【Android】與服務器實現JSON數據通訊

1、前言html

  做爲一名移動端開發人員,具有必定的服務端開發能力也是很是必要的,本篇博客講述如何在Android和服務器之間實現JSON數據通訊交互,博客內容基於另一篇博客:【Web】Eclipse + Maven + Struts搭建服務器java

 

2、服務器端改造android

  在博客【Web】Eclipse + Maven + Struts搭建服務器中,咱們實現了服務器的搭建,如今要作的事情就是讓它返回的數據是一個JSON格式的,這樣在得到請求的時候,咱們才能夠獲得JSON數據,其配置改變以下。數據庫

  首先咱們新建一個com.android.display.bean包,新建一個User類,以下:apache

 1 package conm.android.sdisplay.bean;
 2 
 3 public class User {
 4     String id;
 5     String name;
 6     String password;
 7     String say;
 8     public String getId() {
 9         return id;
10     }
11     public void setId(String id) {
12         this.id = id;
13     }
14     public String getName() {
15         return name;
16     }
17     public void setName(String name) {
18         this.name = name;
19     }
20     public String getPassword() {
21         return password;
22     }
23     public void setPassword(String password) {
24         this.password = password;
25     }
26     public String getSay() {
27         return say;
28     }
29     public void setSay(String say) {
30         this.say = say;
31     }
32 }
View Code

  修改HelloAction代碼以下:json

 1 package com.android.displaymain;
 2 
 3 import java.util.HashMap;
 4 import java.util.Map;
 5 
 6 import com.opensymphony.xwork2.ActionSupport;
 7 
 8 import conm.android.sdisplay.bean.User;
 9 
10 public class HelloAction extends ActionSupport{
11     //將會被Struts2序列化爲JSON字符串的對象
12     private Map<String, Object> dataMap;
13     
14     @Override
15     public String execute() throws Exception {
16         // dataMap中的數據將會被Struts2轉換成JSON字符串,因此這裏要先清空其中的數據
17         dataMap = new HashMap<String, Object>();
18         User user = new User();
19         user.setId("123");
20         user.setName("Android");
21         user.setPassword("abcdefg");
22         user.setSay("Hello world !");
23         dataMap.put("user", user);
24         // 放入一個是否操做成功的標識
25         dataMap.put("success", true);
26         // 返回結果
27         return SUCCESS;
28     }
29 
30     public Map<String, Object> getDataMap() {
31         return dataMap;
32     }
33 
34     public void setDataMap(Map<String, Object> dataMap) {
35         this.dataMap = dataMap;
36     }
37 }
View Code

  咱們的目標是將dataMap以JSON格式返回。如今Action已經完成了,可是還須要配置一下,修改struts.xml文件以下:瀏覽器

 1 <?xml version="1.0" encoding="UTF-8" ?>
 2 <!DOCTYPE struts PUBLIC
 3     "-//Apache Software Foundation//DTD Struts Configuration 2.3//EN"
 4     "http://struts.apache.org/dtds/struts-2.3.dtd">
 5     
 6 <struts>
 7 <package name="com.android.server" namespace="/" extends="json-default" >
 8     <default-action-ref name="index"/>
 9     
10     <action name="index">  
11        <result>/index.jsp</result>      <!-- index.htm爲項目根目錄的默認頁面 -->  
12     </action>
13     
14     <action name="HelloAction" class="com.android.displaymain.HelloAction" method="execute">
15         <result type="json"> <!-- 這裏指定將被Struts2序列化的屬性,該屬性在action中必須有對應的getter方法 -->
16              <param name="root">dataMap</param>
17         </result>
18     </action>
19 </package> 
20 </struts>
View Code

  注意兩處改動,一是package的extends屬性,二是HelloAction的結果返回類型,已經變爲json,而且咱們聲明瞭一個叫作root的param,其值就是咱們要JSON化的屬性,至於爲何要聲明,待會兒能夠測試一下。服務器

  修改完以後,咱們由於使用JSON,須要Struts作必定的工做,咱們就須要引入新的jar包,將pom文件改成:app

 1 <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
 2   xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
 3   <modelVersion>4.0.0</modelVersion>
 4   <groupId>com.android.network</groupId>
 5   <artifactId>network_server</artifactId>
 6   <packaging>war</packaging>
 7   <version>0.0.1-SNAPSHOT</version>
 8   <name>network_server Maven Webapp</name>
 9   <url>http://maven.apache.org</url>
10   <dependencies>
11     <dependency>
12       <groupId>junit</groupId>
13       <artifactId>junit</artifactId>
14       <version>3.8.1</version>
15       <scope>test</scope>
16     </dependency>
17     <dependency>
18             <groupId>org.apache.struts</groupId>
19             <artifactId>struts2-core</artifactId>
20             <version>2.3.16</version>
21         </dependency>
22         <dependency>
23             <groupId>org.apache.commons</groupId>
24             <artifactId>commons-io</artifactId>
25             <version>1.3.2</version>
26         </dependency>
27         <dependency>
28             <groupId>org.apache.struts</groupId>
29             <artifactId>struts2-json-plugin</artifactId>
30             <version>2.3.4</version>
31         </dependency>
32         <dependency>
33             <groupId>commons-lang</groupId>
34             <artifactId>commons-lang</artifactId>
35             <version>2.3</version>
36         </dependency>
37   </dependencies>
38   <build>
39     <finalName>network_server</finalName>
40   </build>
41 </project>
View Code

  這裏增添了兩個jar包,最重要的一個是struts2-json-plugin。jsp

  配置完成,咱們再運行一下工程,運行起來之後,咱們在瀏覽器(注:非IE,不然會要求你下載文件)中輸入網址:http://localhost:8080/display/HelloAction就能夠看到瀏覽器返回的數據:

{"success":true,"user":{"id":"123","name":"Android","password":"abcdefg","say":"Hello world !"}}

  很明顯,服務器端已經正確返回咱們須要的JSON數據了!讀者能夠去掉struts.xml配置中的關於root的配置,看看結果就明白這段配置的含義了。接下來就看Android端的了。

 

3、Android客戶端構建

  Android實現的目標是:向服務器發送請求,而且攜帶參數,展現返回的JSON數據。Android環境的搭建就不贅述啦~直接進入正題。

  發起請求的Activity以下:

 1 package com.example.androidjson;
 2 
 3 import java.io.IOException;
 4 
 5 import org.apache.http.HttpResponse;
 6 import org.apache.http.HttpStatus;
 7 import org.apache.http.client.ClientProtocolException;
 8 import org.apache.http.client.HttpClient;
 9 import org.apache.http.client.methods.HttpPost;
10 import org.apache.http.impl.client.DefaultHttpClient;
11 import org.apache.http.util.EntityUtils;
12 
13 import android.app.Activity;
14 import android.os.Bundle;
15 import android.os.Handler;
16 import android.os.Message;
17 import android.view.View;
18 import android.view.View.OnClickListener;
19 import android.widget.Button;
20 import android.widget.TextView;
21 
22 public class MainActivity extends Activity {
23     TextView textView;
24     Button dataButton;
25     Handler mainHandler;
26     
27     @Override
28     protected void onCreate(Bundle savedInstanceState) {
29         super.onCreate(savedInstanceState);
30         setContentView(R.layout.activity_main);
31         
32         textView = (TextView)findViewById(R.id.textView);
33         dataButton = (Button)findViewById(R.id.dataButton);
34         
35         mainHandler = new Handler(){
36 
37             @Override
38             public void handleMessage(Message msg) {
39                 // TODO Auto-generated method stub
40                 textView.setText(msg.obj.toString());
41             }
42         };
43         
44         dataButton.setOnClickListener(new OnClickListener(){
45             @Override
46             public void onClick(View v) {
47                 // TODO Auto-generated method stub
48                 Thread thread = new Thread(){
49                     @Override
50                     public void run() {
51                         // TODO Auto-generated method stub
52                         sendData();
53                     }
54                 };
55                 
56                 thread.start();
57             }
58         });
59     }
60     
61     private void sendData(){
62         HttpClient httpClient = new DefaultHttpClient();
63         HttpPost httpPost = new HttpPost("http://192.168.0.102:8080/display/HelloAction");
64         try {
65             HttpResponse httpResponse = httpClient.execute(httpPost);
66             if (httpResponse.getStatusLine().getStatusCode() == HttpStatus.SC_OK) { 
67                   // 取得返回的數據 
68                   Message msg = mainHandler.obtainMessage(0, EntityUtils.toString(httpResponse.getEntity()));
69                   mainHandler.sendMessage(msg);
70             } 
71         } catch (ClientProtocolException e) {
72             // TODO Auto-generated catch block
73             e.printStackTrace();
74         } catch (IOException e) {
75             // TODO Auto-generated catch block
76             e.printStackTrace();
77         } 
78     }
79 }
View Code

  按下按鈕後返回結果以下:

到這裏,基本功能已經完成,咱們能夠發起請求,獲取到正確的JSON格式數據了。接下來就是解析JSON數據格式了~

  修改一下服務器端的HelloAction代碼以下:

 1 package com.android.displaymain;
 2 
 3 import java.util.HashMap;
 4 import java.util.Map;
 5 
 6 import com.opensymphony.xwork2.ActionSupport;
 7 
 8 import conm.android.sdisplay.bean.User;
 9 
10 public class HelloAction extends ActionSupport{
11     //將會被Struts2序列化爲JSON字符串的對象
12     private Map<String, Object> dataMap;
13     
14     private String name;
15     
16     @Override
17     public String execute() throws Exception {
18         // dataMap中的數據將會被Struts2轉換成JSON字符串,因此這裏要先清空其中的數據
19         dataMap = new HashMap<String, Object>();
20         User user = new User();
21         user.setId("123");
22         user.setName(name);
23         user.setPassword("abcdefg");
24         user.setSay("Hello world !");
25         dataMap.put("user", user);
26         // 放入一個是否操做成功的標識
27         dataMap.put("success", true);
28         // 返回結果
29         return SUCCESS;
30     }
31 
32     public Map<String, Object> getDataMap() {
33         return dataMap;
34     }
35 
36     public void setDataMap(Map<String, Object> dataMap) {
37         this.dataMap = dataMap;
38     }
39 
40     public String getName() {
41         return name;
42     }
43 
44     public void setName(String name) {
45         this.name = name;
46     }
47 }
View Code

  這裏要求咱們傳入一個參數name,而且設置到返回值中去。如今,咱們的目標是經過JSON向服務器端發送帶參數請求,並正確解析返回的數據。修改Activity代碼以下:

  1 package com.example.androidjson;
  2 
  3 import java.io.IOException;
  4 import java.util.ArrayList;
  5 
  6 import org.apache.http.HttpEntity;
  7 import org.apache.http.HttpResponse;
  8 import org.apache.http.HttpStatus;
  9 import org.apache.http.NameValuePair;
 10 import org.apache.http.client.ClientProtocolException;
 11 import org.apache.http.client.HttpClient;
 12 import org.apache.http.client.entity.UrlEncodedFormEntity;
 13 import org.apache.http.client.methods.HttpPost;
 14 import org.apache.http.impl.client.DefaultHttpClient;
 15 import org.apache.http.message.BasicNameValuePair;
 16 import org.apache.http.protocol.HTTP;
 17 import org.apache.http.util.EntityUtils;
 18 import org.json.JSONException;
 19 import org.json.JSONObject;
 20 
 21 import android.app.Activity;
 22 import android.os.Bundle;
 23 import android.os.Handler;
 24 import android.os.Message;
 25 import android.view.View;
 26 import android.view.View.OnClickListener;
 27 import android.widget.Button;
 28 import android.widget.TextView;
 29 
 30 public class MainActivity extends Activity {
 31     TextView textView;
 32     Button dataButton;
 33     Handler mainHandler;
 34     
 35     @Override
 36     protected void onCreate(Bundle savedInstanceState) {
 37         super.onCreate(savedInstanceState);
 38         setContentView(R.layout.activity_main);
 39         
 40         textView = (TextView)findViewById(R.id.textView);
 41         dataButton = (Button)findViewById(R.id.dataButton);
 42         
 43         mainHandler = new Handler(){
 44 
 45             @Override
 46             public void handleMessage(Message msg) {
 47                 // TODO Auto-generated method stub
 48                 parseJSON(msg.obj.toString());
 49             }
 50         };
 51         
 52         dataButton.setOnClickListener(new OnClickListener(){
 53             @Override
 54             public void onClick(View v) {
 55                 // TODO Auto-generated method stub
 56                 Thread thread = new Thread(){
 57                     @Override
 58                     public void run() {
 59                         // TODO Auto-generated method stub
 60                         sendData();
 61                     }
 62                 };
 63                 
 64                 thread.start();
 65             }
 66         });
 67     }
 68     
 69     private void parseJSON(String result){
 70         JSONObject jsonObj;
 71         try {
 72             jsonObj = new JSONObject(result);
 73             boolean resResult = jsonObj.getBoolean("success");
 74             JSONObject userObj = jsonObj.getJSONObject("user");
 75             String id = userObj.getString("id"); 
 76             String name = userObj.getString("name"); 
 77             String say = userObj.getString("say"); 
 78             textView.setText("ID: "+ id + "\n姓名: " + name + "\n性別: " + say);
 79         } catch (JSONException e) {
 80             // TODO Auto-generated catch block
 81             e.printStackTrace();
 82         }
 83     }
 84     
 85     private void sendData(){
 86         HttpClient httpClient = new DefaultHttpClient();
 87         HttpPost httpPost = new HttpPost("http://192.168.0.102:8080/display/HelloAction");
 88         try {
 89             ArrayList<NameValuePair> list = new ArrayList<NameValuePair>(); 
 90             list.add(new BasicNameValuePair("name", "大腳印")); 
 91             HttpEntity en = new UrlEncodedFormEntity(list, HTTP.UTF_8); 
 92             httpPost.setEntity(en); 
 93             HttpResponse httpResponse = httpClient.execute(httpPost);
 94             if (httpResponse.getStatusLine().getStatusCode() == HttpStatus.SC_OK) { 
 95                   // 取得返回的數據 
 96                   Message msg = mainHandler.obtainMessage(0, EntityUtils.toString(httpResponse.getEntity()));
 97                   mainHandler.sendMessage(msg);
 98             } 
 99         } catch (ClientProtocolException e) {
100             // TODO Auto-generated catch block
101             e.printStackTrace();
102         } catch (IOException e) {
103             // TODO Auto-generated catch block
104             e.printStackTrace();
105         } 
106     }
107 }
View Code

  點擊Send Data 按鈕:

至此,咱們已經能夠完成從數據庫返回JSON格式的數據,而且正確解析數據~

 

5、總結

  突發奇想,想要本身走一遍Android客戶端到服務器之間的數據傳遞流程,因此花了點時間研究了一下~

  使用JSON傳遞數據很是簡單,尤爲是當服務器使用Struts2時可使用插件支持該功能,更是很是方便~

 

客戶端 & 服務器端示例代碼下載

相關文章
相關標籤/搜索