JSON

网络通信过程中的数据如何进行结构组织,比较熟悉的有两种方式,JSON和XML,应用都非常广泛,个人项目里使用的是JSON,本文主要是要对JSON的解析做一下总结。

1.关于为何选择JSON

      首先JSON和XML都是一种数据交换格式(不应该叫做通信协议)

      通信协议:通过通信信道和设备互连起来的多个不同地理位置的数据通信系统,要使其能协同工作实现信息交换和资源共享,它们之间必须具有共同的语言。交流什么、怎样交流及何时交流,都必须遵循某种互相都能接受的规则。这个规则就是通信协议

-->我们自己在JSON上定义的C/S数据传输体系整体可以看做一个简单的通信协议。

      JSON和XML的比较,网络上的信息很多,大致可以参考
      http://blog.sina.com.cn/s/blog_6cbdddcb0100m37c.html

实用中的感受就是,XML的可读性相对较好,大量标签使得内容容易被看懂,但这既成就了XML的有点也造就了它的缺点,冗余信息要比JSON大很多,考虑在移动网络环境下,数据传输时间对用户体验的巨大影响,JSON的高效率低冗余就非常有吸引力了。

      从json的全称JavaScript Object Notation就可以猜测它跟JavaScript的“亲戚”关系,其实这个轻量级的数据交换格式是基于JavaScript的一个子集,说白了就是js的对象和数组,所以json对JSP的支持非常好。json采用了独立于语言的文本格式,有两种基本数据结构:对象和数组(两者各种嵌套形成较复杂的json数据)。
      Json Array放在中括号[]里面,如[a,c,d...],就跟我们熟悉的数组没本质区别。数组中的元素可以是string, number, false, true, null, Object对象甚至是array数组。下面是官网给的图解:


 


      Json Object放在大括号{}里面,表示成键值对{key1:value1, key2:value2, key3:value3,....}。其中(在面向对象的语言里)key为对象的属性,value为对应的属性值。key只能是string类型的, 而value可以是string, number, false, true, null, Object对象甚至是array数组, 也就是说可以存在嵌套的情况。下面是官网给的图解:



解析json数据首先需要知道解析的是json数组还是json对象

 

2.JSON的封装和解析。

      APP(Android)和Server通信通信,这里面,涉及到两端各自的信息封装和解析。总体上,可以找到这三个库可供使用:

net.sf.json

Gson(use on Android)

Org.json(use on Android)

     之间的比较总结如下:

      net.sf.json:无论是封装还是解析都最方便直接,且支持的解析方式较方便(可映射为Map,List,对象等非常使用的格式),所以在server端使用。但是在我视图将其引入Android上使用时,发现存在不兼容现象。

      Android上对于Json的解析有Gson和Org.json两个库可供使用,这个库的实用性接近(但都没有net.sf.json好用)。因为一般发送的数据请求报文都较短,所以在封装上的差异相对不明显。但解析数据时,数据量可能会很大,格式也复杂。对于解析这两个库各有自己的特点,Org.json相对来说更适合去解析层次较多的信息,它能方便的执行一层一层剥开提取的操作;而Gson的面对这种层次较多的数据解析则繁琐的多,但是它有一个特性Org.json没有,Gson库可以直接进行jsonstring和Object以及List<Object>之间的映射,因此,如果json串本身的信息结构就非常简单,且里面的信息本身就是一个一个对象信息,则用Gson做解析代码会意想不到的精简。


这篇博客中有GSON的解析可参考:http://my.eoe.cn/bupt/archive/15365.html?f=nge

下面是我自己项目中的代码:

使用Gson进行封装的代码:

/*Gson封装:工程中使用封装的地方较多,单件模式,简单工厂,最终需要构造的json串如下:
{"data":{"password":"00000","username":"admin"},"head":{"stream_num":0,"message_type":10000,"flag":0,"protocol_version":1}}
*/
public static Gson getGson(){
    if(gson==null){
        GsonBuilder builder = new GsonBuilder();   
        builder.excludeFieldsWithoutExposeAnnotation();  
        gson = builder.create();  
    }
    return gson;
}
 
/*封装的过程是先将数据存到Map中,然后统一转换*/
public static String encapLoginInfor( String username, String password ) {
        
        Map<String,Integer> headDetail = new HashMap<String,Integer>();
        headDetail.put("protocol_version", 1);
        headDetail.put("flag", 0);
        headDetail.put("message_type", 10000);
        headDetail.put("stream_num", 0);
 
        Map<String,String> dataDetail = new HashMap<String,String>();
        dataDetail.put("username", username);
        dataDetail.put("password", password);
 
        Map<String,Map> finalProtocalMap = new HashMap<String,Map>();
        finalProtocalMap.put("head", headDetail);
        finalProtocalMap.put("data", dataDetail);
 
        String mapToJson = getGson().toJson(finalProtocalMap);
        return mapToJson;
    }

使用Gson解析:

public class ParseJSONStringUtil {
    /*使用Gson解析*/
    public static Gson gson;
 
    public static Gson getGson(){
        if(gson==null){
            GsonBuilder builder = new GsonBuilder();   
            builder.excludeFieldsWithoutExposeAnnotation();  
            gson = builder.create();  
        }
        return gson;
    }
    
    /*直接进行串和对象之间的映射,下面的CommonHeader.class即传来的json串对应的类*/
    public static CommonHeader parseCommonHeader( String head )
    {
        CommonHeader commonheader = getGson().fromJson(head, CommonHeader.class);
        return commonheader; 
    }
}
下面是使用到的CommonHeader类:
package common;
 
public class CommonHeader {
    
    private short version;
    private short flag;           
    private short messageType;  
    private short streamId;
 
    public CommonHeader( short aVersion, short aFlag, short aMessageType, short aStreamId ) {
        version = aVersion;
        flag = aFlag;
        messageType = aMessageType;
        streamId = aStreamId;
    }
    
    public short getVersion() {
        return version;
    }
 
    public short getFlag() {
        return flag;
    }
 
    public short getMessageType() {
        return messageType;
    }
 
    public short getStreamId() {
        return streamId;
    }
}

 


使用Org.json解析:基本思想就是按照Array和Object逐步解析

JSONTokener jsonParser = new JSONTokener(str);
    try {
           JSONObject infor = (JSONObject)jsonParser.nextValue();
           JSONObject headOj= infor.getJSONObject("head");
           String messageType = headOj.getString("message_type");
           if(messageType.equals("11001")){
                JSONObject dataOj = infor.getJSONObject("data");
                            JSONArray daArray =  dataOj.getJSONArray("DAResult");
                            for(int i=0;i<daArray.length();i++){ 
                                JSONObject temp = (JSONObject)daArray.opt(i); 
                                System.out.println((Integer.parseInt(temp.getString("id"))));
                            }
            }
        }

(本例中代码解析和封装基本都是针对代码一开头注释中的jsonstring)

郑重声明:本站内容如果来自互联网及其他传播媒体,其版权均属原媒体及文章作者所有。转载目的在于传递更多信息及用于网络分享,并不代表本站赞同其观点和对其真实性负责,也不构成任何其他建议。