个人google-gson使用总结,JSON的序列化和反序列化

来源:互联网 发布:南风捏脸数据网盘 编辑:程序博客网 时间:2024/06/07 07:20

首先确定下什么是json。

一 JSON

  

JSON是一种取代XML的数据结构,和xml相比,它更小巧但描述能力却不差,由于它的小巧所以网络传输数据将减少更多流量从而加快速度,

那么,JSON到底是什么?

JSON就是一串字符串 只不过元素会使用特定的符号标注。

{} 双括号表示对象

[] 中括号表示数组

"" 双引号内是属性或值

: 冒号表示后者是前者的值(这个值可以是字符串、数字、也可以是另一个数组或对象)

所以 {"name": "Michael"} 可以理解为是一个包含name为Michael的对象

而[{"name": "Michael"},{"name": "Jerry"}]就表示包含两个对象的数组

当然了,你也可以使用{"name":["Michael","Jerry"]}来简化上面一部,这是一个拥有一个name数组的对象

ps:现在还有很多人存在一些误区,为什么{name:'json'}在检验时通过不了,

那是因为JSON官网最新规范规定

如果是字符串,那不管是键或值最好都用双引号引起来,所以上面的代码就是{"name":"json"}

不要反驳,官网就是这么定义的。

二使用gson解析json

 (一)需要google-json的jar包:gson-2.2.4.jar(本人用的是这个版本,下载地址:http://download.csdn.net/detail/a7564951/8613361)

还有个httpclient的包:commons-httpclient-3.1.jar,下载地址:http://download.csdn.net/detail/skyxuyan/5146887

 (二)项目功能:通过请求URL(http://j.cailizhong.com/data/issue/ah11x5/20140607),把得到的json解析成一个List<String[]>对象供使用

    1 首先确认json对象的格式定义一个Bean,定义bean参阅:http://blog.csdn.net/tkwxty/article/details/34474501

很多时候大家都是不知道这个Bean是该怎么定义,这里面需要注意几点:
             1、类里面的属性名必须跟Json字段里面的Key是一模一样的;
             2、内部嵌套的用[]括起来的部分是一个List,这里整体是一个List<
IssueBean>;而只用{}嵌套的就定义为IssueBean
                  具体的大家对照Json字符串看看就明白了,不明白的也可以看开头json定义,引号的即是字段值了,必须一致!

  这里用的json格式如下:

    

String json=[{"game":"ah11x5","issue":"2014060781","code":"07,10,08,05,11","time":"2014-06-07 22:02:10"},{"game":"ah11x5","issue":"2014060780","code":"02,09,11,07,10","time":"2014-06-07 21:52:10"},{"game":"ah11x5","issue":"2014060779","code":"09,04,08,10,01","time":"2014-06-07 21:42:10"}];

实体类Bean如下IssueBean.java:

package com.bozhong.bean;import com.google.gson.annotations.Expose;public class IssueBean {//@Expose注解用于定义序列化和反序列化的字段,严格按照json格式定义@Expose    private String game;@Expose    private String issue ;@Expose    private String code ;@Expose    private String time ;@Expose    private String starttime ;@Expose    private String endtime ;@Exposeprivate String[] info;public String[] getInfo() {return info;}public void setInfo(String[] info) {this.info = info;}public String getStarttime() {return starttime;}public void setStarttime(String starttime) {this.starttime = starttime;}public String getEndtime() {return endtime;}public void setEndtime(String endtime) {this.endtime = endtime;}public String getGame() {return game;}public void setGame(String game) {this.game = game;}public String getIssue() {return issue;}public void setIssue(String issue) {this.issue = issue;}public String getCode() {return code;}public void setCode(String code) {this.code = code;}public String getTime() {return time;}public void setTime(String time) {this.time = time;}}
注:7行的注解表示可序列化的字段,这里定义的字段和json格式比较,变量名和字段名一致,注解详细参阅:

http://blog.csdn.net/andywuchuanlong/article/details/44077913

    2 新建一个工具类Util.java 

package com.bozhong.utils;import java.io.BufferedReader;import java.io.InputStreamReader;import java.io.OutputStreamWriter;import java.lang.reflect.Type;import java.net.HttpURLConnection;import java.net.URL;import java.util.ArrayList;import java.util.List;import com.bozhong.bean.IssueBean;import com.google.gson.Gson;import com.google.gson.GsonBuilder;import com.google.gson.annotations.Expose;import com.google.gson.reflect.TypeToken;public class Util {     public static String sendUrl(String urlString, String params, boolean isPost) throws Exception {     //详细的HttpURLConnection用法可参阅:http://blog.csdn.net/x1617044578/article/details/8668632  URL url = new URL(urlString); // 此处的url.openConnection()对象实际上是根据URL的          // 请求协议(此处是http)生成的URLConnection类          // 的子类HttpURLConnection,故此处最好将其转化          // 为HttpURLConnection类型的对象,以便用到          // HttpURLConnection更多的API. HttpURLConnection conn = (HttpURLConnection) url.openConnection(); // 设置是否向conn输出,因为这个涉及到post请求,参数要放在      // http正文内,因此需要设为true, 默认情况下是false;如果单是get请求设置不设置无所谓 conn.setDoOutput(true);  if (isPost) {  // 此处getOutputStream会隐含的进行conn.connect(); //现在创建一个输入流对象, OutputStreamWriter writer = new OutputStreamWriter( conn.getOutputStream()); //把post请求的数据写入输入流,这些数据将存到内存缓冲区中  writer.write(params); // 刷新对象输出流,将任何字节都写入潜在的流中 writer.flush(); // 关闭流对象。此时,不能再向对象输出流写入任何数据,先前写入的数据存在于内存缓冲区中,     // 在调用下边的conn.getInputStream()函数时才把准备好的http请求正式发送到服务器  writer.close(); } // 调用HttpURLConnection连接对象的getInputStream()函数,    // 将内存缓冲区中封装好的完整的HTTP请求电文发送到服务端。并赋给InputStreamReader InputStreamReader reder = new InputStreamReader(conn.getInputStream(), "utf-8"); //利用BufferedReader输出接收到的json数据 BufferedReader breader = new BufferedReader(reder); String content = ""; String result = "";  //breader.readLine()方法会逐行读取json数据,直到本行为null while ((content = breader.readLine()) != null) { //简单字符串拼接 result += content + "\n"; } return result; }     /*      * http://j.cailizhong.com/data/issue/ah11x5/20140607      * 利用上面地址获取安徽11x5中奖号码,这个网站比较稳定,可以用来实现定时任务的更新数据库      * 最终方法,每天更新昨天的数据      */          public static List<String[]> getIssueCode(String url) {     //创建一个List<String[]>用于接受处理好的json数据    List<String[]> listNew = new ArrayList<String[]>();    //创建GsonBuilder对象,excludeFieldsWithoutExposeAnnotation()方法用于识别    //实体类IssueBean中@Expose得注解,实现序列化和反序列化 GsonBuilder gsonBuilder = new GsonBuilder() .excludeFieldsWithoutExposeAnnotation(); //创建Gson对象,用于序列化json--->list Gson gson = gsonBuilder.create(); Type issueType; List<IssueBean> list=null; String json = ""; try { // json=GetPS.sendUrl("http://j.cailizhong.com/data/issue/ah11x5/20140607", // "", true); json = Util .sendUrl(url,"", true); //String json2 = json.substring(22, json.length() - 2); //String json3 = "[" + json + "]"; System.out.println("json+++++++" + json); // 定义json要转化成对象的类型,这里是带泛型的List  issueType = new TypeToken<List<IssueBean>>() { }.getType(); // json转为带泛型的list list = gson.fromJson(json, issueType); System.out.println("0.0.0++++======" + list); } catch (Exception e) { System.out.println(e.toString()); e.printStackTrace(); } //对象处理,这里把List<IssueBean>处理成自己想要的List<String[]> for(int i=0;i<list.size();i++){ String[] li=new String[3]; li[0]=list.get(i).getIssue(); li[1]=list.get(i).getCode(); li[2]=list.get(i).getTime(); listNew.add(li); } return listNew; }          public static void main(String[] args) {     List<String[]> listNew = new ArrayList<String[]>();     //最终方法     listNew=getIssueCode("http://j.cailizhong.com/data/issue/ah11x5/20140607"); System.out.println("lsitNew的长度为++++"+listNew.size());     System.out.println("遍历集合listNew---------------开始");     for(int i=0;i<listNew.size();i++){     //System.out.println(listNew.get(i));     String[] str=listNew.get(i);     System.out.println("遍历数组str============开始");     for(int j=0;j<str.length;j++){     System.out.println(str[j]);     }     System.out.println("遍历数组str============结束");     }     System.out.println("遍历集合listNew---------------结束");    }}
75行的new GsonBuilder().excludeFieldsWithoutExposeAnnotation(),调用这个方法才能识别IssueBean里的注解@Expose,

  识别其他注解和类型等的请参与:http://blog.csdn.net/lk_blog/article/details/7685190

三 扩展复杂Json,例如下面字符串

String json={"errorCode":0,"data":[{"dateNumber":"15041981","id":"514","dateTime":"2015-04-19 22:00:00","list":["10","08","02","01","11"]},{"dateNumber":"15041980","id":"514","dateTime":"2015-04-19 21:50:00","list":["08","05","06","02","04"]},{"dateNumber":"15041979","id":"514","dateTime":"2015-04-19 21:40:00","list":["05","10","01","06","09"]},{"dateNumber":"15041978","id":"514","dateTime":"2015-04-19 21:30:00","list":["06","11","05","01","10"]},{"dateNumber":"15041977","id":"514","dateTime":"2015-04-19 21:20:00","list":["03","07","08","06","04"]},{"dateNumber":"15041976","id":"514","dateTime":"2015-04-19 21:10:00","list":["07","02","05","06","04"]}]}
方法一,当成一个对象,因为上例中要把整体当做一个List对待,json中list是用[]包围的,所以需要加上一对[],如下

String json2="["+json+"]";

实体类bean如下:

package com.bozhong.bean;import java.util.List;import com.google.gson.annotations.Expose;public class Ah11x5Bean {@Exposeprivate String errorCode;@Exposeprivate List<data> data;//B内部类形式public static class data{@Exposeprivate String dateNumber;@Exposeprivate String id;@Exposeprivate String dateTime;@Exposeprivate String[] list;public String getDateNumber() {return dateNumber;}public void setDateNumber(String dateNumber) {this.dateNumber = dateNumber;}public String getDateTime() {return dateTime;}public void setDateTime(String dateTime) {this.dateTime = dateTime;}public String getId() {return id;}public void setId(String id) {this.id = id;}public String[] getList() {return list;}public void setList(String[] list) {this.list = list;}}public String getErrorCode() {return errorCode;}public void setErrorCode(String errorCode) {this.errorCode = errorCode;}public List<data> getData() {return data;}public void setData(List<data> data) {this.data = data;}}
Warning:1 如果不添加[],将会抛出异常如下,证明解析过程中,符号不匹配,按照开头的json定义,仔细检查很容易发现

2如果缺少注解@Expose ,值将会获得不到或者报空指针异常,说明序列化失败


方法二:如果只需要data的值得话,可以截取,如下

String json2 = json.substring(22, json.length()-2);

这样相对的Bean相对简单,如下

package com.bozhong.bean;import com.google.gson.annotations.Expose;public class Ah11x5DataBean {@Exposeprivate String dateNumber;@Exposeprivate String id;@Exposeprivate String dateTime;@Exposeprivate String[] list;public String getDateNumber() {return dateNumber;}public void setDateNumber(String dateNumber) {this.dateNumber = dateNumber;}public String getId() {return id;}public void setId(String id) {this.id = id;}public String getDateTime() {return dateTime;}public void setDateTime(String dateTime) {this.dateTime = dateTime;}public String[] getList() {return list;}public void setList(String[] list) {this.list = list;}}


  本人第一次总结,并且是新手,如有错误欢迎指出,交流,互相学习,补正,谢谢,如有用大家互相学习

最后附上源码下载地址,可以直接运行:http://yunpan.cn/cVb6eqZbUT9s2  访问密码 aa7c

 



1 0
原创粉丝点击