JSON解析
来源:互联网 发布:自学编程看什么书 编辑:程序博客网 时间:2024/05/01 02:21
原生org.json.JSONObject;
1.创建
对于程序员来说,大多数都是解析JSON数据,但是创建JSON数据也是很有必要了解一下的。
(1)对象包含对象
public class CreateJSON {public static void main(String[] args) throws Exception {// 创建一个空白的obj对象JSONObject obj = new JSONObject();// 给obj存放信息obj.put("id",001);obj.put("name", "张三");obj.put("sex", "男");obj.put("score", 99.5);System.out.println(obj);//一个对象包含另一个对象JSONObject schooloobj = new JSONObject();schooloobj.put("schoolName", "北京大学");schooloobj.put("address", "不知道");schooloobj.put("student", obj);System.out.println(schooloobj);}}打印结果:
{"address":"不知道","student":{"score":99.5,"sex":"男","name":"张三","id":1},"schoolName":"北京大学"}
放入顺序和显示顺序不同,原因在于底层使用Map存储方式,其实服务器就是这样给客户端提供数据的,只需要把syso改成write即可。
(2)对象包含数组的
public class CreateJSON {public static void main(String[] args) throws Exception {JSONObject schooloobj = new JSONObject();schooloobj.put("schoolName", "北京大学");schooloobj.put("address", "不知道");//存放数组JSONArray array = new JSONArray();for(int i=0;i<3;i++){JSONObject obj = new JSONObject();obj.put("id", i);obj.put("name", "李四"+i);obj.put("age", 15+i);array.put(obj);}schooloobj.put("student", array);System.out.println(schooloobj);}}打印结果:
{"address":"不知道","student":[{"name":"李四0","id":0,"age":15},{"name":"李四1","id":1,"age":16},{"name":"李四2","id":2,"age":17}],"schoolName":"北京大学"}
由于是键值对形式存放,所以Values不能为null,但实际需求中往往存在很多空 解决方案:obj.put("key","null");或obj.put("key","");,
2.解析
JSON的解析数据千奇百怪,没有一个例子能够完全说明,只能通过他们的特点来解析,下面来看一下简单
例子1
public class ParseJSON {public static void main(String[] args) throws JSONException {String json = "{persons:[{name:'zhangsan',age:20},"+ "{name:'lisi',age:21}," + "{name:'wangwu',age:22}]}";JSONObject obj = new JSONObject(json);JSONArray array = obj.getJSONArray("persons");for(int i=0;i<array.length();i++){JSONObject obj2 = array.getJSONObject(i);String name = obj2.getString("name");int age = obj2.getInt("age");System.out.println(name+"\t"+age);}}}打印结果:
zhangsan 20
lisi 21
wangwu 22
例子2:
public class ParseJSON {public static void main(String[] args) throws JSONException {String json = "[{name:'张三',scores:{en:90,math:99,cn:89}},"+ "{name:'李四',scores:{en:80,math:90,cn:99}}]";JSONArray arr = new JSONArray(json);for(int i=0;i<arr.length();i++){JSONObject obj2 = arr.getJSONObject(i);String name = obj2.getString("name");JSONObject scores = obj2.getJSONObject("scores");String en = scores.getString("en");//JSON数据给出的是int型数据,这里用String也是可以解析的int math = scores.getInt("math");int cn = scores.getInt("cn");System.out.println(name+"\t"+en+"\t"+math+"\t"+cn);}}}打印结果:
张三 90 99 89
李四 80 9099
解析的小技巧:
解析的时候先看最外面的是{}还是[],前者就JSONObject 后者就JSONArray按照此规律一直往下扒,到了{"student":[{"name":"zhangsan"},{"name",lisi}]}的时候obj.getJSONArray("student")得到的是数组,数字再次循环遍历得到object对象就可以了。在实际解析过程中经常出现空指针异常,这很大的原因的解析的数据为null,JSON数据为空有三种,"" , "null" , null 上述三种可以使用都是空,但只有null报错,可以使用isNull(key)判断,不等于空的时候在取值,另外getString有没有值都拿 而 optString 在没有值的情况下给你默认值,int 是0,字符串不是null,是""。
阿里com.alibaba.fastjson
1.创建 to
fastjson解析和创建必须有实体类的支持,并且JSON字符串的Key和实体类的属性一一对应,并且必须有get set方法,如果没有get set方法,就算有实体类也无法创建JSON字符串
下面是一一对应的例子1(未给出实体类)
public class ParseJSON {public static void main(String[] args) throws JSONException {Student s = new Student(1, "张三", "nan");Object object = JSON.toJSON(s);System.out.println(object.toString());}}
例子2:
public class CreateJsonString {public static void main(String[] args) {//生成集合的json字符串List<Student> list=new ArrayList<Student>();for (int i = 0; i < 5; i++) {Student ss=new Student(i,"张三"+i,"男");list.add(ss);}//对象套集合{ []}School s=new School();s.setName("清华");s.setAddress("不知道");s.setNumber(1000);s.setStudents(list);String jsonString=JSON.toJSONString(s);System.out.println(jsonString);}}
2.解析 parse
如果实体类是属性比JSON字符串的key少,那么属性有多少存多少,其他忽视,如果实体类的属性比JSON字符串的Key多,那么JSON字符串的Key有多少给实体类存多少,其他的是类属性的默认值。fastjson解析相对来说容易了许多,构建相同的实体类即可,这里只给出Test.java类,源码下载地址:http://download.csdn.net/detail/u010829905/8877673
public class ParseJSON {public static void main(String[] args) throws JSONException {String url = "http://weather.xcyh.org/json/7";HttpUtil.getImage(url, new CallBack() {@Overridepublic void getByteImage(byte[] b) {String stu = new String(b,Charset.forName("GBK"));String newstu = decodeUnicode(stu);Beijing object = JSON.parseObject(newstu, Beijing.class);System.out.println(object.getData().get(1).getTemperature());//至此解析完成了}});}//网络请求是unicode编码,下面方法的解决的//方法来源:http://ruixiazun.blog.163.com/blog/static/906879182013112439117/ public static String decodeUnicode(String theString) { char aChar; int len = theString.length(); StringBuffer outBuffer = new StringBuffer(len); for (int x = 0; x < len;) { aChar = theString.charAt(x++); if (aChar == '\\') { aChar = theString.charAt(x++); if (aChar == 'u') { // Read the xxxx int value = 0; for (int i = 0; i < 4; i++) { aChar = theString.charAt(x++); switch (aChar) { case '0': case '1': case '2': case '3': case '4': case '5': case '6': case '7': case '8': case '9': value = (value << 4) + aChar - '0'; break; case 'a': case 'b': case 'c': case 'd': case 'e': case 'f': value = (value << 4) + 10 + aChar - 'a'; break; case 'A': case 'B': case 'C': case 'D': case 'E': case 'F': value = (value << 4) + 10 + aChar - 'A'; break; default: throw new IllegalArgumentException( "Malformed \\uxxxx encoding."); } } outBuffer.append((char) value); } else { if (aChar == 't') aChar = '\t'; else if (aChar == 'r') aChar = '\r'; else if (aChar == 'n') aChar = '\n'; else if (aChar == 'f') aChar = '\f'; outBuffer.append(aChar); } } else outBuffer.append(aChar); } return outBuffer.toString(); }}
由于上述链接请求下来的JSON数据是unicode编码格式,普通的转换无法完成,所以找了上述方法 public static String decodeUnicode(String theString)该方法来源:http://ruixiazun.blog.163.com/blog/static/906879182013112439117/
例子2:
{
"date": "20150708",
"stories": [
{
"images": [
"http://pic4.zhimg.com/f926183839b3fadfbdaf4fb82fbc4da3.jpg"
],
"type": 0,
"id": 4849292,
"ga_prefix": "070817",
"title": "饿了 · 完全不关乎厨艺,好做到想笑的冬荫功汤"
},
]
"top_stories": [
{
"image": "http://pic2.zhimg.com/010646d8235df4bbf959a83069283f25.jpg",
"type": 0,
"id": 4849730,
"ga_prefix": "070813",
"title": "我是参加这次救火行动的某券商交易员"
},
]
}
蓝色字体代表两个数组,数组内容大致相同(不同也可以,建实体类的时候取交集),两个数组JSON.parseArray();两次就能得到全部数据
紫色字体代表解析的关键点,既数组内无{}而是"" 在解析的时候把他当成{},st变量进行增强for遍历的时候st就是去除[]的URL了 images实体类为List<String> images;
public class JSON两个差不多的解析 {public static void main(String[] args) {String url="http://news-at.zhihu.com/api/4/stories/latest";HttpUtil.getByte(url, new CallBack() {//该回调方法将得到的entity返回 byte[] @Overridepublic void getByte(byte[] b) {try {//解析storiesString strJSON = new String(b,"utf-8");JSONObject obj = new JSONObject(strJSON);String strstories= obj.getString("stories");List<Story> arr = JSON.parseArray(strstories,Story.class);for (Story s : arr) {System.out.println("ID:"+s.getId());System.out.println("标题:"+s.getTitle());List<String> images = s.getImages();for (String st : images) {System.out.println("URL:"+st);}}//解析top_storiesString top_stories = obj.getString("top_stories");arr=JSON.parseArray(top_stories, Story.class);System.out.println("分割线----------------------------------------------------------------");for (Story s : arr) {System.out.println("ID:"+s.getId());System.out.println("标题:"+s.getTitle());System.out.println("图片:"+s.getImage());}} catch (UnsupportedEncodingException e) {e.printStackTrace();} catch (JSONException e) {// TODO Auto-generated catch blocke.printStackTrace();}}});}}其实通过上面的例子可以看出,fast-json 有相对应的key和value最好,没有对应属性则该实体类无法得到值,属性多余key时为默认值,并且跟类名无关,上面解析的key为stories,而类名为Story。
总结:
1.解析完成的数据存入实体类或者Map集合,没有实体类的时候用Map集合。但fastjson无法完成Map集合
2.原生JSON一层一层解析,虽然麻烦点,但是灵活度相对较高,不依赖实体类。
fastjson解析方便,代码简洁,缺点必须依赖实体类,
3.二者相结合使用很方便。
- 【JSON解析】JSON解析
- 解析JSON
- Json解析
- JSON解析
- JSON解析
- json解析
- Json解析
- Json解析
- JSON解析
- Json解析
- Json解析
- JSON解析
- JSON解析
- json 解析
- Json解析
- JSON解析
- json解析
- json 解析
- 给navigationbar添加背景图片,并且按比例延伸
- Material Design in Action — 哔哩哔哩动画 Android 客户端
- 黑马程序员——java基础---IO流(第18天)
- xib中的拾色器与代码RGB的色差
- PIVOT和UNPIVOT使用详解
- JSON解析
- KMP算法
- 时钟类
- 实现数据的反序
- Javascript 小技巧
- 最长不降子序列
- 《权威指南》笔记 -- 8.2 函数调用
- 2012年5月SAT香港真题解析
- MySQL详解(21)------------缓存参数优化