首先确定下什么是json。
一 JSON
JSON是一种取代XML的数据结构,和xml相比,它更小巧但描述能力却不差,由于它的小巧所以网络传输数据将减少更多流量从而加快速度,
那么,JSON到底是什么?
JSON就是一串字符串 只不过元素会使用特定的符号标注。
{} 双括号表示对象
[] 中括号表示数组
"" 双引号内是属性或值
: 冒号表示后者是前者的值(这个值可以是字符串、数字、也可以是另一个数组或对象)
所以 {"name": "Michael"} 可以理解为是一个包含name为Michael的对象
而[{"name": "Michael"},{"name": "Jerry"}]就表示包含两个对象的数组
当然了,你也可以使用{"name":["Michael","Jerry"]}来简化上面一部,这是一个拥有一个name数组的对象
那是因为JSON官网最新规范规定
如果是字符串,那不管是键或值最好都用双引号引起来,所以上面的代码就是{"name":"json"}
不要反驳,官网就是这么定义的。
二使用gson解析json
(一)需要google-json的jar包:gson-2.2.4.jar(本人用的是这个版本,下载地址:http://download.youkuaiyun.com/detail/a7564951/8613361)
还有个httpclient的包:commons-httpclient-3.1.jar,下载地址:http://download.youkuaiyun.com/detail/skyxuyan/5146887
(二)项目功能:通过请求URL(http://j.cailizhong.com/data/issue/ah11x5/20140607),把得到的json解析成一个List<String[]>对象供使用
1 首先确认json对象的格式定义一个Bean,定义bean参阅:http://blog.youkuaiyun.com/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.youkuaiyun.com/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.youkuaiyun.com/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.youkuaiyun.com/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定义,仔细检查很容易发现
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 {
@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