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 上进行修改,修改如下所示
- /**
 - * @param value :JSON 名值对中的值,值可以有多种类型
 - * @return
 - */
 - // 使用Gson方式接受对象转换为JSON数据格式并且作为字符串输出.
 - public static String createJsonString(Object value){
 - Gson gson = new Gson();
 - String str = gson.toJson(value);
 - return str;
 - }
 
这边做这个修改主要是因为在GSON中将Java对象转换成JSON字符串的时候是不带key的值,这一点与上一讲中讲JSON字符串的形式是不一样的
2). 在JsonAction.java 上做对应的调用修改
- // 根据不同的参数输出不同的JSON数据
 - String jsonString = "";
 - String action_flag = request.getParameter("action_flag");
 - if(action_flag.equals("person")) {
 - jsonString = JsonTools.createJsonString(service.getPerson());
 - } else if(action_flag.equals("persons")){
 - jsonString = JsonTools.createJsonString(service.getListPerson());
 - } else if(action_flag.equals("listString")) {
 - jsonString = JsonTools.createJsonString(service.getListString());
 - } else if(action_flag.equals("listMap")){
 - jsonString = JsonTools.createJsonString(service.getListMaps());
 - }
 
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
2). MainActivity.java
- package com.android.gsonproject.gson;
 - import java.util.ArrayList;
 - import java.util.List;
 - import java.util.Map;
 - import com.google.gson.Gson;
 - import com.google.gson.reflect.*;
 - public class GsonTools {
 - public GsonTools() {
 - }
 - /*
 - * 查看Gson api其中的fromJson(String json, Class<T> classOfT)方法
 - * public <T> T fromJson(String json, Class<T> classOfT)
 - * 用来描述一个特殊的Json对象,使用反射机制可以将JSON字符串中包含的内容赋值给指定的类。这边的T表示的是通过泛型,也就是可以表示任意的类型。
 - * 参数说明:
 - * json : 指定对象解析过的JSON字符串源,用来转换回Java对象。
 - * classOfT : 泛型 T 的Class对象。
 - */
 - public static <T> T getPerson(String jsonString, Class<T> cls){
 - T t = null;
 - try {
 - Gson gson = new Gson();
 - t = gson.fromJson(jsonString, cls);
 - } catch (Exception e) {
 - // TODO: handle exception
 - }
 - return t;
 - }
 - /*
 - * List 我们使用的Gson中的
 - * public <T> T fromJson(String json, Type typeOfT)
 - * 这边我们需要取到List<T>中不同的对象,普通的实现方式就如上一讲中org.Json库来解析JSON的方式一样(读者阅读上一讲内容),
 - * 这里我们通过 Gson中的 TypeToken类是简便操作:这边typeOfT的用法是通过反射机制把T里面的对象的属性的值映射出来,然后通过将json字符串取得的值赋值上去就可以了。
 - * getType()的意思就是表示将jsonString的字符串解析出来之后封装到List集合中,然后分别从T里面取出类型将其复制。
 - */
 - public static <T> List<T> getPersons(String jsonString, Class<T> cls){
 - List<T> list = new ArrayList<T>();
 - try {
 - Gson gson = new Gson();
 - list = gson.fromJson(jsonString,
 - new TypeToken<List<T>>(){}.getType());
 - } catch (Exception e) {
 - // TODO: handle exception
 - }
 - return list;
 - }
 - public static List<String> getList(String jsonString){
 - List<String> list = new ArrayList<String>();
 - try {
 - Gson gson = new Gson();
 - list = gson.fromJson(jsonString,
 - new TypeToken<List<String>>(){}.getType());
 - } catch (Exception e) {
 - // TODO: handle exception
 - }
 - return list;
 - }
 - public static List<Map<String, Object>> getListMaps(String jsonString){
 - List<Map<String, Object>> list = new ArrayList<Map<String,Object>>();
 - try {
 - Gson gson = new Gson();
 - list = gson.fromJson(jsonString,
 - new TypeToken<List<Map<String, Object>>>(){}.getType());
 - } catch (Exception e) {
 - // TODO: handle exception
 - }
 - return list;
 - }
 - }
 
- @Override
 - public void onClick(View v) {
 - switch (v.getId()) {
 - case R.id.person:
 - String path = "http://192.168.0.112:8080/JsonProject/servlet/JsonAction?action_flag=person";
 - String jsonString = HttpUtils.getJsonContent(path);
 - Log.i(TAG, "The jsonString:" + jsonString);
 - Person person = GsonTools.getPerson(jsonString, Person.class);
 - Log.i(TAG, "The person:" + person.toString());
 - break;
 - case R.id.persons:
 - String path2 = "http://192.168.0.112:8080/JsonProject/servlet/JsonAction?action_flag=persons";
 - String jsonStr2 = HttpUtils.getJsonContent(path2);
 - Log.i(TAG, "The jsonString:" + jsonStr2);
 - List<Person> list = GsonTools.getPersons(jsonStr2, Person.class);
 - Log.i(TAG, "The person:" + list.toString());
 - break;
 - case R.id.liststring:
 - String path3 = "http://192.168.0.112:8080/JsonProject/servlet/JsonAction?action_flag=listString";
 - String jsonStr3 = HttpUtils.getJsonContent(path3);
 - Log.i(TAG, "The jsonString:" + jsonStr3);
 - List<String> list3 = GsonTools.getList(jsonStr3);
 - Log.i(TAG, "The person:" + list3.toString());
 - break;
 - case R.id.listmap:
 - String path4 = "http://192.168.0.112:8080/JsonProject/servlet/JsonAction?action_flag=listMap";
 - String jsonStr4 = HttpUtils.getJsonContent(path4);
 - Log.i(TAG, "The jsonString:" + jsonStr4);
 - List<Map<String, Object>> list4 = GsonTools.getListMaps(jsonStr4);
 - Log.i(TAG, "The person:" + list4.toString());
 - break;
 - }
 - }
 
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
                    
                
                
            
        
浙公网安备 33010602011771号