天天看点

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

首先确定下什么是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 ;
	@Expose
	private 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 {
	@Expose
	private String errorCode;
	@Expose
	private List<data> data;
	//B内部类形式
	public static class data{
		@Expose
		private String dateNumber;
		@Expose
		private String id;
		@Expose
		private String dateTime;
		@Expose
		private 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定义,仔细检查很容易发现

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

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

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

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

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

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

package com.bozhong.bean;

import com.google.gson.annotations.Expose;

public class Ah11x5DataBean {
	@Expose
	private String dateNumber;
	@Expose
	private String id;
	@Expose
	private String dateTime;
	@Expose
	private 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