Android 之json解析

JSON(JavaScript Object Notation) 定义:字符串 键值对 解析方法有JSON,谷歌GSON,阿里巴巴FastJSON(推荐)

 

一种轻量级的数据交换格式,具有良好的可读和便于快速编写的特性。

业内主流技术为其提供了完整的解决方案(有点类似于正则表达式,获得了当今大部分语言的支持),从而可以在不同平台间进行数据交换。

JSON采用兼容性很高的文本格式,同时也具备类似于C语言体系的行为。

Json建构于两种结构:
1.“名称/值”对的集合(A collection of name/value pairs):不同的语言中,它被理解为对象(object),纪录(record),结构(struct),字典(dictionary),哈希表(hash table),有键列表(keyed list),或者关联数组 (associative array)。
ØJSON对象是一个无序的“‘名称/值’对”集合。一个对象以“{”(左括号)开始,“}”(右括号)结束。
每个“名称”后跟一个“:”(冒号);“‘名称/值’ 对”之间使用“,”(逗号)分隔。如: {“name”:”jackson”, “age”:100}
 
2.值的有序列表(An ordered list of values)。在大部分语言中,它被理解为数组(array)
Ø数组是值(value)的有序集合。一个数组以“[”(左中括号)开始,“]”(右中括号)结束。值之间使用“,”(逗号)分隔
如:{  “students”:  [  {“name”:”jackson”,“age”:100},  {“name”:”michael”,”age”:51}  ]  }

JSON解析JSON数据时的重要方法

(1)JSONObject:

这是系统中有关JSON定义的基本单元,其包含一对(Key/Value)数值。

它对外部(External:应用toString()方法输出的数值)调用的响应体现为一个标准的字符串(例如:{“JSON”: “Hello, World”},最外被大括号包裹,其中的Key和Value被冒号”:”分隔)。

其对于内部(Internal)行为的操作格式略微,例如:初始化一个JSONObject实例,引用内部的put()方法添加数值:new JSONObject().put(“JSON”, “Hello, World!”),在Key和Value之间是以逗号”,”分隔。

Value的类型包括:Boolean、JSONArray、JSONObject、Number、String或者默认值JSONObject.NULL object。

有两个不同的取值方法:

get(): 在确定数值存在的条件下使用,否则当无法检索到相关Key时,将会抛出一个Exception信息。

opt(): 这个方法相对比较灵活,当无法获取所指定数值时,将会返回一个默认数值,并不会抛出异常。

(2)JSONArray:

它代表一组有序的数值。将其转换为String输出(toString)所表现的形式是用方括号包裹,数值以逗号”,”分隔(例如:[value1,value2,value3],大家可以亲自利用简短的代码更加直观的了解其格式)。这个类的内部同样具有查询行为,get()和opt()两种方法都可以通过index索引返回指定的数值,put()方法用来添加或者替换数值。

同样这个类的value类型可以包括:Boolean、JSONArray、JSONObject、Number、String或者默认值JSONObject.NULL object。

示例:服务器端生成json数据,客户端读取并解析json数据

(3)JSONStringer:

根据官方的解释,这个类可以帮助快速和便捷的创建JSONtext。其最大的优点在于可以减少由于格式的错误导致程序异常,引用这个类可以自动严格按照JSON语法规则(syntaxrules)创建JSON text。每个JSONStringer实体只能对应创建一个JSON text。

根据下边的实例来了解其它相关信息:String myString = new JSONStringer().object() .key("name").value("小猪") .endObject().toString();

String myString = new JSONStringer().object()

.key("name")

.value("小猪")

.endObject()

.toString();
结果是一组标准格式的JSON text:{"name" : "小猪"}

其中的.object()和.endObject()必须同时使用,是为了按照Object标准给数值添加边界。同样,针对数组也有一组标准的方法来生成边界.array()和.endArray()。

 

示例1:
服务器端编写
1.首先导入json的各种包
2.JsonTools  如何将不同的数据类型如何生成json格式的字符串
View Code

3.JsonService  将person对象返回不同数据类型,供JsonTools  生成json

person

View Code

JsonService  

View Code

4.TestJson 测试JsonTools  是否可以正常将JsonService 中返回的各种类型转换成json格式的字符串

5.JsonAction servlet 响应客户端的action  首先实例化JsonService 对象 并在init()方法中初始化该对象  doget做dopost的内容,并完善dopost

View Code

客户端编写

1.首先在清单文件中添加访问网络的授权

2.修改布局文件

View Code

3.为了访问服务器端数据,编写http工具类,将访问url返回的输入流转换成String返回

View Code

4.由于服务器端是将person对象按照不同的格式加工成json格式的字符串返回给客户端,而客户端需要将字符串解析出来还原成为一个相应格式的person对象,所以客户端也需要定义一个person类

View Code

5.重点编写json解析类JsonTools,完成解析,要求给方法一个key和一个json字符串,就按照要求还原出来

View Code

 ---------------------------------------

谷歌GSON技术

Gson这个Java类库可以把Java对象转换成JSON,也可以把JSON字符串转换成一个相等的Java对象。
Gson支持任意复杂Java对象包括没有源代码的对象。
示例2:
服务器端:在上例中修改部分代码
1.导入包
2.修改JsonTools  去掉key
View Code

3.JsonService  不变

4.修改action 因为gson的方法没有key值,所以得去掉

就这样 修改就完成了

客户端编写:

1.首先还是网络授权、并导入第三包

2.布局文件添加按钮

View Code

3.http、person同上

4.gsonTools 由于服务器生成json的时候没有key,所以与jsonTools不一样 gson.fromJson(jsonString, cls);或者gson.fromJson(jsonString);

使用到了反射的概念,服务器端和客户端解析和逆解析的对象都是同样的对象(在这里是person),使用jsonTools解析对象的时候,需要指明返回的类型,

但是使用gsonTools则采用泛型,使得gsonTools成为一个工具类,即不论服务器端返回何种类型的对象,客户端只要知道返回的类型都能进行解析,不用知道传递什么类型,也不用返回既定的类型

T指的是通用泛型,可以指任意的数据类型

View Code

 4.mainactivity

 1 package com.android.gson;
 2 
 3 
 4 import java.util.List;
 5 import java.util.Map;
 6 
 7 import com.android.gson.domain.Person;
 8 import com.android.gson.gsonTools.GsonTools;
 9 import com.android.gson.http.HttpUtils;
10 import com.example.android_05json_gson.R;
11 
12 import android.app.Activity;
13 import android.os.Bundle;
14 import android.util.Log;
15 import android.view.Menu;
16 import android.view.MenuItem;
17 import android.view.View;
18 import android.view.View.OnClickListener;
19 import android.widget.Button;
20 
21 public class MainActivity extends Activity implements OnClickListener{
22     private Button person, persons, liststring, listmap;
23     private static final String TAG = "MainActivity";
24     @Override
25     protected void onCreate(Bundle savedInstanceState) {
26         super.onCreate(savedInstanceState);
27         setContentView(R.layout.activity_main);
28         person = (Button) this.findViewById(R.id.person);
29         persons = (Button) this.findViewById(R.id.persons);
30         liststring = (Button) this.findViewById(R.id.liststring);
31         listmap = (Button) this.findViewById(R.id.listmap);
32         person.setOnClickListener(this);
33         persons.setOnClickListener(this);
34         liststring.setOnClickListener(this);
35         listmap.setOnClickListener(this);
36     }
37 
38     @Override
39     public boolean onCreateOptionsMenu(Menu menu) {
40         // Inflate the menu; this adds items to the action bar if it is present.
41         getMenuInflater().inflate(R.menu.main, menu);
42         return true;
43     }
44 
45     @Override
46     public boolean onOptionsItemSelected(MenuItem item) {
47         // Handle action bar item clicks here. The action bar will
48         // automatically handle clicks on the Home/Up button, so long
49         // as you specify a parent activity in AndroidManifest.xml.
50         int id = item.getItemId();
51         if (id == R.id.action_settings) {
52             return true;
53         }
54         return super.onOptionsItemSelected(item);
55     }
56 
57     @Override
58     public void onClick(View v) {
59         // TODO Auto-generated method stub
60         switch (v.getId()) {
61         case R.id.person:
62             String path = "http://122.206.79.193:8080/gsonProject/servlet/JsonAction?action_flag=person";
63             String jsonString = HttpUtils.getJsonContent(path);
64             Person person=GsonTools.getPerson(jsonString, Person.class);
65             Log.i(TAG, person.toString());
66             break;
67         case R.id.persons:
68             String path2 = "http://122.206.79.193:8080/gsonProject/servlet/JsonAction?action_flag=persons";
69             String jsonString2 = HttpUtils.getJsonContent(path2);
70             List<Person> list=GsonTools.getPersons(jsonString2, Person.class);
71             Log.i(TAG, list.toString());
72             break;
73         case R.id.liststring:
74             String path3 = "http://122.206.79.193:8080/gsonProject/servlet/JsonAction?action_flag=liststring";
75             String jsonString3 = HttpUtils.getJsonContent(path3);
76             List<String> list3=GsonTools.getList(jsonString3);
77             Log.i(TAG, list3.toString());
78             break;
79         case R.id.listmap:
80             String path4 = "http://122.206.79.193:8080/gsonProject/servlet/JsonAction?action_flag=listmap";
81             String jsonString4 = HttpUtils.getJsonContent(path4);
82             List<Map<String,Object>> list4=GsonTools.listKeyMaps(jsonString4);
83             Log.i(TAG, list4.toString());
84             break;
85         }
86     }
87 }
View Code

 

 ---------------------------------------

阿里巴巴FastJson技术

 ØFastJson是一个Json处理工具包,包括“序列化”和“反序列化”两部分,它具备如下特征:速度最快,测试表明,fastjson具有极快的性能,超越任其他的Java Json parser。包括自称最快的JackJson。功能强大,完全支持Java Bean、集合、Map、日期、Enum,支持范型,支持自省。无依赖,能够直接运行在Java SE 5.0以上版本.支持Android。开源 (Apache 2.0)

示例:只需要讲gson客户端稍加修改即可
1.首先卸载gson的包,并引用fastJson的包
2.FastJsonTools最不同,
返回单个对象:JSON.parseObject(jsonString, cls);
返回List<T>JSON.parseArray(jsonString, cls);

返回List<Map<String, Object>>JJSON.parseObject(jsonString,new TypeReference<List<Map<String, Object>>>() {});

 1 package com.android.gson.fastJsonTools;
 2 import java.util.ArrayList;
 3 import java.util.List;
 4 import java.util.Map;
 5 
 6 import com.alibaba.fastjson.JSON;
 7 import com.alibaba.fastjson.TypeReference;
 8 
 9 ;
10 public class FastJsonTools {
11 
12     public FastJsonTools() {
13         // TODO Auto-generated constructor stub
14     }
15 
16     /**
17      * @param <T>
18      * @param jsonString
19      * @param cls
20      * @return单条数据单个javabean
21      */
22     public static <T> T getPerson(String jsonString, Class<T> cls) {
23         T t = null;
24         try {
25             t = JSON.parseObject(jsonString, cls);
26         } catch (Exception e) {
27             // TODO: handle exception
28         }
29         return t;
30     }
31 
32     /**
33      * 使用Gson进行解析 List<Person>
34      * 
35      * @param <T>
36      * @param jsonString
37      * @param cls
38      * @return
39      */
40     public static <T> List<T> getPersons(String jsonString, Class<T> cls) {
41         List<T> list = new ArrayList<T>();
42         try {
43             list = JSON.parseArray(jsonString, cls);
44         } catch (Exception e) {
45         }
46         return list;
47     }
48 
49     
50 
51     public static List<Map<String, Object>> listKeyMaps(String jsonString) {
52         List<Map<String, Object>> list = new ArrayList<Map<String, Object>>();
53         try {
54             list = JSON.parseObject(jsonString,
55                     new TypeReference<List<Map<String, Object>>>() {
56             });
57         } catch (Exception e) {
58             // TODO: handle exception
59         }
60         return list;
61     }
62 }
View Code

 

 

三种方式的对比:

 

方式 是否提供服务器端jsonString的生成方法 客户端JsonTools中的方法
JSON 是:JSONObject jsonObject = new JSONObject();

jsonObject.put(key, value);

解析成单个对象:方法参数为key和jsonString

JSONObject jsonObject = new JSONObject(jsonString);
JSONObject personObject = jsonObject.getJSONObject("person");

赋值之后 return对象;

解析成List<对象>:方法参数为key和jsonString

JSONObject jsonObject = new JSONObject(jsonString);
// 返回json的数组
JSONArray jsonArray = jsonObject.getJSONArray(key);

遍历并 list.add(对象)之后,返回list

解析成List<String>:方法参数为key和jsonString

JSONObject jsonObject = new JSONObject(jsonString);
JSONArray jsonArray = jsonObject.getJSONArray(key);

遍历并 list.add(对象)之后,返回list

 

解析成List<String>

List<Map<String, Object>> :方法参数为key和jsonString

JSONObject jsonObject = new JSONObject(jsonString);
JSONArray jsonArray = jsonObject.getJSONArray(key);
for (int i = 0; i < jsonArray.length(); i++) {
JSONObject jsonObject2 = jsonArray.getJSONObject(i);

遍历jsonObject2 并 list.add(map)之后,返回list

谷歌GSON 是:

Gson gson = new Gson();
String gstr = gson.toJson(value);

 解析成单个对象:方法参数为String jsonString, Class<T> cls

Gson gson = new Gson();
t = gson.fromJson(jsonString, cls);

return t即可

 解析成List<对象>:方法参数为key和jsonString方法参数为String jsonString, Class<T> cls

Gson gson = new Gson();
list = gson.fromJson(jsonString, new TypeToken<List<T>>() {
}.getType());

return list;

 解析成List<String>:方法参数为jsonString

Gson gson = new Gson();
list = gson.fromJson(jsonString, new TypeToken<List<String>>() {
}.getType());

return list;

  解析成List<Map<String, Object>>

Gson gson = new Gson();
list = gson.fromJson(jsonString,
new TypeToken<List<Map<String, Object>>>() {
}.getType());

return list;

阿里巴巴FastJSON

 解析成单个对象:方法参数为String jsonString和 Class<T> cls

t = JSON.parseObject(jsonString, cls);

return t即可

 解析成List<T>  list = JSON.parseArray(jsonString, cls);

return list;

 解析成List<Map<String, Object>>方法参数为String jsonString

list = JSON.parseObject(jsonString,
new TypeReference<List<Map<String, Object>>>() {
});

return list;

 

posted @ 2015-11-15 22:26  孟想阳光  阅读(479)  评论(0编辑  收藏  举报