Android客户端与服务端之间使用GSON交互数据。

 前面我们有提到google的Gson技术的介绍[GSON 数据格式详解],这一讲我们来详细学习一下Android客户端与服务端之间使用GSON进行JSON数据的解析,关于GSON的技术我们已经在前面两讲中提到过,对GSON不了解的读者可以先去看前面两讲的博文,这一讲我们主要学习一下使用GSON方式来完成Android客户端与服务端之间的JSON数据的交互,具体的实现Demo我们会在上面一讲[Android客户端与服务端之间使用JSON交互数据]的Demo架构上进行修改,读者在看这一部分的内容的时候可以从上面一讲中看起。

    这一讲我们主要来实现一下使用Gson完成JSON字符串与Java对象之间的转换,如下图所示

一. 服务端:作用是使用GSON将服务端的对象转换成JSON数据格式

我们服务端主要是基于上一讲的解析JSON的服务端架构进行修改,读者可以先看完上一讲内容再参考此文。

1. 添加gson的jar库到lib目录下
2. 查看GSON API com.google.gson.Gson类,这个是最经常使用的类

This is the main class for using Gson. Gson is typically used by first constructing a Gson instance and then invoking toJson(Object) or fromJson(String, Class) methods on it. 

3. 代码如下

1). JSONTools.java 上进行修改,修改如下所示

 

[java] view plain copy
 
 在CODE上查看代码片派生到我的代码片
  1. /** 
  2.  * @param value :JSON 名值对中的值,值可以有多种类型 
  3.  * @return 
  4.  */  
  5. // 使用Gson方式接受对象转换为JSON数据格式并且作为字符串输出.  
  6. public static String createJsonString(Object value){  
  7.     Gson gson = new Gson();  
  8.     String str = gson.toJson(value);  
  9.     return str;  
  10. }   

 

   这边做这个修改主要是因为在GSON中将Java对象转换成JSON字符串的时候是不带key的值,这一点与上一讲中讲JSON字符串的形式是不一样的

2). 在JsonAction.java 上做对应的调用修改

 

[java] view plain copy
 
 在CODE上查看代码片派生到我的代码片
  1. // 根据不同的参数输出不同的JSON数据  
  2. String jsonString = "";  
  3. String action_flag = request.getParameter("action_flag");  
  4. if(action_flag.equals("person")) {  
  5.     jsonString = JsonTools.createJsonString(service.getPerson());  
  6. else if(action_flag.equals("persons")){  
  7.     jsonString = JsonTools.createJsonString(service.getListPerson());  
  8. else if(action_flag.equals("listString")) {  
  9.     jsonString = JsonTools.createJsonString(service.getListString());  
  10. else if(action_flag.equals("listMap")){  
  11.     jsonString = JsonTools.createJsonString(service.getListMaps());  
  12. }  

 

3). 在浏览器地址栏中访问查看是否返回JSON数据,下面就贴出一个例子,另外几个读者可以自己参考根据参数的不同去尝试。

地址栏输入:http://192.168.0.112:8080/JsonProject/servlet/JsonAction?action_flag=listMap
返回:[{"id":1,"color":"red","name":"Polu"},{"id":7,"color":"green","name":"Zark"}]

说明服务端的使用GSON将对象转换成JSON数据格式成功了

二. 客户端:工作是利用GSON将服务端转换好的JSON字符串转换成指定的对象。

1. 导入gson库

这里有一个简单的方法构建jar库,在项目工程上右击 --> new --> Folder --> 取名libs,然后将gson的jar包复制进去(如果已经存在libs文件夹则直接复制进去)然后选中所有导入的jar包右击 --> Build Path --> Add to Build Path 即可。

2. 程序Demo

1). GsonTools.java

 

[java] view plain copy
 
 在CODE上查看代码片派生到我的代码片
  1. package com.android.gsonproject.gson;  
  2.   
  3. import java.util.ArrayList;  
  4. import java.util.List;  
  5. import java.util.Map;  
  6.   
  7. import com.google.gson.Gson;  
  8. import com.google.gson.reflect.*;  
  9. public class GsonTools {  
  10.   
  11.     public GsonTools() {  
  12.       
  13.     }  
  14.   
  15.     /* 
  16.      * 查看Gson api其中的fromJson(String json, Class<T> classOfT)方法 
  17.      * public <T> T fromJson(String json, Class<T> classOfT) 
  18.      * 用来描述一个特殊的Json对象,使用反射机制可以将JSON字符串中包含的内容赋值给指定的类。这边的T表示的是通过泛型,也就是可以表示任意的类型。 
  19.      * 参数说明: 
  20.      * json : 指定对象解析过的JSON字符串源,用来转换回Java对象。 
  21.      * classOfT : 泛型   T 的Class对象。 
  22.      */  
  23.     public static <T> T getPerson(String jsonString, Class<T> cls){  
  24.         T t = null;  
  25.         try {  
  26.             Gson gson = new Gson();  
  27.             t = gson.fromJson(jsonString, cls);  
  28.         } catch (Exception e) {  
  29.             // TODO: handle exception  
  30.         }  
  31.         return t;  
  32.     }  
  33.       
  34.     /* 
  35.      * List 我们使用的Gson中的 
  36.      * public <T> T fromJson(String json, Type typeOfT) 
  37.      * 这边我们需要取到List<T>中不同的对象,普通的实现方式就如上一讲中org.Json库来解析JSON的方式一样(读者阅读上一讲内容), 
  38.      * 这里我们通过 Gson中的 TypeToken类是简便操作:这边typeOfT的用法是通过反射机制把T里面的对象的属性的值映射出来,然后通过将json字符串取得的值赋值上去就可以了。 
  39.      * getType()的意思就是表示将jsonString的字符串解析出来之后封装到List集合中,然后分别从T里面取出类型将其复制。 
  40.      */  
  41.       
  42.     public static <T> List<T> getPersons(String jsonString, Class<T> cls){  
  43.         List<T> list = new ArrayList<T>();  
  44.         try {  
  45.             Gson gson = new Gson();  
  46.             list = gson.fromJson(jsonString,   
  47.                     new TypeToken<List<T>>(){}.getType());  
  48.         } catch (Exception e) {  
  49.             // TODO: handle exception  
  50.         }  
  51.         return list;  
  52.     }  
  53.       
  54.     public static List<String> getList(String jsonString){  
  55.         List<String> list = new ArrayList<String>();  
  56.         try {  
  57.             Gson gson = new Gson();  
  58.             list = gson.fromJson(jsonString,   
  59.                     new TypeToken<List<String>>(){}.getType());  
  60.         } catch (Exception e) {  
  61.             // TODO: handle exception  
  62.         }  
  63.         return list;  
  64.     }  
  65.       
  66.     public static List<Map<String, Object>> getListMaps(String jsonString){  
  67.         List<Map<String, Object>> list = new ArrayList<Map<String,Object>>();  
  68.         try {  
  69.             Gson gson = new Gson();  
  70.             list = gson.fromJson(jsonString,   
  71.                     new TypeToken<List<Map<String, Object>>>(){}.getType());  
  72.         } catch (Exception e) {  
  73.             // TODO: handle exception  
  74.         }  
  75.         return list;  
  76.     }  
  77. }  
2). MainActivity.java
[java] view plain copy
 
 在CODE上查看代码片派生到我的代码片
  1. @Override  
  2. public void onClick(View v) {  
  3.     switch (v.getId()) {  
  4.         case R.id.person:  
  5.             String path = "http://192.168.0.112:8080/JsonProject/servlet/JsonAction?action_flag=person";  
  6.             String jsonString = HttpUtils.getJsonContent(path);  
  7.             Log.i(TAG, "The jsonString:" + jsonString);  
  8.             Person person = GsonTools.getPerson(jsonString, Person.class);  
  9.             Log.i(TAG, "The person:" + person.toString());  
  10.             break;  
  11.   
  12.         case R.id.persons:  
  13.             String path2 = "http://192.168.0.112:8080/JsonProject/servlet/JsonAction?action_flag=persons";  
  14.             String jsonStr2 = HttpUtils.getJsonContent(path2);  
  15.             Log.i(TAG, "The jsonString:" + jsonStr2);  
  16.             List<Person> list = GsonTools.getPersons(jsonStr2, Person.class);  
  17.             Log.i(TAG, "The person:" + list.toString());  
  18.             break;  
  19.               
  20.         case R.id.liststring:  
  21.             String path3 = "http://192.168.0.112:8080/JsonProject/servlet/JsonAction?action_flag=listString";  
  22.             String jsonStr3 = HttpUtils.getJsonContent(path3);  
  23.             Log.i(TAG, "The jsonString:" + jsonStr3);  
  24.             List<String> list3 = GsonTools.getList(jsonStr3);  
  25.             Log.i(TAG, "The person:" + list3.toString());  
  26.             break;  
  27.               
  28.         case R.id.listmap:  
  29.             String path4 = "http://192.168.0.112:8080/JsonProject/servlet/JsonAction?action_flag=listMap";  
  30.             String jsonStr4 = HttpUtils.getJsonContent(path4);  
  31.             Log.i(TAG, "The jsonString:" + jsonStr4);  
  32.             List<Map<String, Object>> list4 = GsonTools.getListMaps(jsonStr4);  
  33.             Log.i(TAG, "The person:" + list4.toString());  
  34.             break;  
  35.     }  
  36. }  

 

3. [备注知识]

我们这里使用的Class<T>是一个什么概念?

  老罗的说法:由于服务端和客户端所解析的对象虽然是一致的,但是必须要满足不管服务端传递什么对象,客户端只要知道服务端传递的对象类型,就可以解析出来的。(他的表述我听的很混)

  我自己的理解:Android客户端需要解析服务端的不同类型的对象,所以这边使用泛型来表示,而无论一个类new出多少个对象,它们对应的class对象是一致的(这点是Java的反射机制决定的),而Gson也运用了Java的反射机制,所以这边的 classOfT参数的意思是 T类型的class对象。

四. 编译执行结果

1. 界面如下所示

2. 第一个按钮

3. 第二个按钮

4. 第三个按钮

5. 第四个按钮

 

   由于整个工程都是基于上一讲Json数据解析来修改和串讲的,读者在单独看这一部分的内容会有迷糊,建议读者可以阅读上一篇博文,然后在看Gson的数据解析这样效果会好很多。

在这里贴出本文的源代码:

客户端:http://download.csdn.NET/my

服务端:http://download.csdn.Net/my

posted @ 2016-11-27 15:38  天涯海角路  阅读(187)  评论(0)    收藏  举报