JSON学习笔记

    xiaoxiao2021-03-25  73


    JSON是什么,有什么用?

          跟XML一样,是一种数据的格式规范。       可以理解成是“XML的简化版”,但与XML无关。

          JSON(JavaScript Object Notation)是一种轻量级的数据交换格式。       基于JS技术发展起来(因此JS对其有更好的支持),但与语言无关,任何语言都可以解析。

          对比:

    XML可读性较高,数据量较大;JSON可读性较低(但比自己随意定义的要好),数据量较小;XML应用主要有3点;JSON主要用于数据交换(存储也可应用,较少);XML应用、发展更广;

    JSON如何定义?

    表示“键值对”/对象

          最简单的形式:

    {"firstName":"Brett"}

          这个示例非常简单,而且实际上比等效的传统的“键值对”占用更多的空间:

    firstName=Brett

          当将多个“键值对”串在一起时,JSON就会体现出它的价值了。

    {"firstName":"Brett","lastName":"McLaughlin","email":"aaaa"}

          这样,可以明确地表示以上三个值都是同一记录的一部分(一个对象),花括号使这些值有了某种联系。

    表示“数组”

    {"people":[   {"firstName":"Brett","lastName":"McLaughlin","email":"aaaa"},   {"firstName":"Jason","lastName":"Hunter","email":"bbbb"},   {"firstName":"Elliotte","lastName":"Harold","email":"cccc"}   ] } 或者: {"programmers":[   {"firstName":"Brett","lastName":"McLaughlin","email":"aaaa"},   {"firstName":"Jason","lastName":"Hunter","email":"bbbb"},   {"firstName":"Elliotte","lastName":"Harold","email":"cccc"} ],   "authors":[   {"firstName":"Isaac","lastName":"Asimov","genre":"science fiction"},   {"firstName":"Tad","lastName":"Williams","genre":"fantasy"},   {"firstName":"Frank","lastName":"Peretti","genre":"christian fiction"} ],   "musicians":[   {"firstName":"Eric","lastName":"Clapton","instrument":"guitar"},   {"firstName":"Sergei","lastName":"Rachmaninoff","instrument":"piano"} ]}

          更多格式规范参考 “JSON格式规范.txt” 。

          如想校验JSON格式是否正确,可参考 http://www.bejson.com。

    如何应用?

    JS对JSON数据的操作

          JSON是JavaScript原生格式,可以直接应用。

          也可使用json.js或jQuery.js这些组件去操作。

    Java对JSON数据的操作

          使用行业组件Jackson。

    JSON格式规范

    {"name": "Michael"} {} 对象 [] 数组 "" 双引号内是属性或值 : 冒号表示后者是前者的值 [{"name": "Michael"},{"name": "Jerry"}] 也可表达成:{"name":["Michael","Jerry"]} ================================================================================= {"sub_int":"a"} true {"sub_int":a} false {"sub_int":100} true,对象 [{"sub_int":100}] true,数组 {123:100} false,属性必须有双引号 {"123":100} true {"sub_int":123.12} true {"sub_int":true} true {"sub_int":null} true {'sub_int':'a'} false,不能用单引号

          JSON 语法是 JavaScript 对象表示法语法的子集。

    数据在名称/值对中:如 “firstName” : “John”数据由逗号分隔花括号保存对象方括号保存数组

          而组成JSON的值可以为以下几种:

    数字(整数或浮点数)字符串(在双引号中)逻辑值(true 或 false)数组(在方括号中)对象(在花括号中)null

    传统的JSON解析

          最传统的JSON解析莫过于直接使用java中的方法,它通过原生的JSONObject和JSONArray来解析json数据,下面我们就来解析这段json数据吧!json数据如下:

    { "personData": [ { "age": 12, "name": "nate", "schoolInfo": [ { "School_name": "清华" }, { "School_name": "北大" } ], "url": "http://pic.yesky.com/uploadImages/2014/345/36/E8C039MU0180.jpg" }, { "age": 24, "name": "jack", ··· } ], "result": 1 }

          分析这段json数据,

    •第一层是一个花括号括号,即jsonObect对象,然后这个对象里面有一个personData的JSONArray数组,以及一个result属性 •第二层personData的JSONArray数组,它里面除了属性之外,还有一个schoolInfo的JSONArray数组 •第三次是schoolInfo的JSONArray数组里面的JSONObject对象

          这时我们已经将这段数据分析好了,接下来就是写解析方法解析了。

          代码如下:

    /** * 从网络中获取JSON字符串,然后解析 * @param json * @return */ private List<Person> jsonParse(String json) { try { List<Person> personlist = new ArrayList<Person>(); JSONObject jsonObject = new JSONObject(json); int result = jsonObject.getInt("result"); if (result == 1) { JSONArray jsonArray = jsonObject.getJSONArray("personData"); for (int i = 0; i < jsonArray.length(); i++) { Person person = new Person(); JSONObject personData = jsonArray.getJSONObject(i); int age = personData.getInt("age"); String url = personData.getString("url"); String name = personData.getString("name"); ··· JSONArray schoolInfoArray = personData.getJSONArray("schoolInfo"); for (int j = 0; j < schoolInfoArray.length(); j++) { JSONObject schoolInfojson = schoolInfoArray.getJSONObject(j); String schoolName = schoolInfojson.getString("School_name"); ··· } ··· } return personlist; } else { Toast.makeText(context, "erro", Toast.LENGTH_SHORT).show(); } } catch (JSONException e) { e.printStackTrace(); Log.e("JsonParseActivity", "json解析出现了问题"); } return null; }

          首先是一个大括号,我们直接从传过来的json字符串创建出来的jsonObject就行了,然后就可以通过它获取result参数,代码如下:

    JSONObject jsonObject = new JSONObject(json); int result = jsonObject.getInt("result");

          然后就是解析personData这个json数组,我们直接通过数组名称获取,代码如下:

    JSONArray jsonArray = jsonObject.getJSONArray("personData");

          再接着就是解析这个数组,解析数组都是用循环解析的,然后这个数组里面先是一个花括号,这又是一个jsonObject对象,代码如下:

    JSONArray jsonArray = jsonObject.getJSONArray("personData"); for (int i = 0; i < jsonArray.length(); i++) { JSONObject personData = jsonArray.getJSONObject(i); int age = personData.getInt("age"); String url = personData.getString("url"); String name = personData.getString("name"); ··· }

          在personData这个JSONObject对象中,又有一个schoolInfo的JSONArray数组,我们继续按照上述方法获得JSONArray,然后通过for循环获得里面的JSONObject,这时已达到最底层,我们就可以直接获取School_name属性的值了,代码如下:

    for (int j = 0; j < schoolInfoArray.length(); j++) { JSONObject schoolInfojson = schoolInfoArray.getJSONObject(j); String schoolName = schoolInfojson.getString("School_name"); ··· }

          这样,一个完整的JSON数据就解析好了!

          当然,这只是解析一个简单的JSON数据的方法,但是遇到复杂的json数据也可以如此解析,首先是分析JSON数据,然后就是正式解析json。

          课后习题:在项目中的res-raw文件夹下,有newjson.txt的json数据,大家可以使用这个来联系一下json解析。当然啦,这个json数据的传统解析方式也在项目里面写好了,如果不懂也可以参考一下!

          再举一个例子

          解析如下json

    { "name": "scnuyz", "subject": [ "c", "java", "sql" ], "msg": { "say": "hello" } } import java.io.IOException; import org.json.JSONArray; import org.json.JSONException; import org.json.JSONObject; public class Demo2 { public static void main(String[] args) throws IOException { String content = "{\"name\": \"scnuyz\",\"subject\": [\"c\",\"java\",\"sql\"],\"msg\":{\"say\":\"hello\"}}"; try { JSONObject jsonObject = new JSONObject(content); String name = jsonObject.getString("name"); JSONArray jsonArray = jsonObject.getJSONArray("subject"); String s1 = (String)jsonArray.get(0); String s2 = (String)jsonArray.get(1); String s3 = (String)jsonArray.get(2); JSONObject aaaJsonObject = jsonObject.getJSONObject("msg"); String say = aaaJsonObject.getString("say"); System.out.println("json:"+content); System.out.println("name:"+name); System.out.println("subject:"+s1+","+s2+","+s3); System.out.println("say:"+say); } catch (JSONException e) { // TODO Auto-generated catch block e.printStackTrace(); } } }

          输出:

    json:{"name": "scnuyz","subject": ["c","java","sql"],"msg":{"say":"hello"}} name:scnuyz subject:c,java,sql say:hello

    JACKSON案例

          Jackson提供了三种可选的Json处理方法:

          流式API(Streaming API) 、树模型(Tree Model)、数据绑定(Data Binding)。

          从使用角度来看,比较一下这三种处理Json的方式的特性:

    Streaming API:是效率最高的处理方式(开销低、读写速度快,但程序编写复杂度高)Tree Model:是最灵活的处理方式Data Binding:是最常用的处理方式

          JACKSON中写一个json文件使用的是JsonGenerator类

    package com.jackson; import java.io.File; import java.io.IOException; import com.fasterxml.jackson.core.JsonEncoding; import com.fasterxml.jackson.core.JsonFactory; import com.fasterxml.jackson.core.JsonGenerationException; import com.fasterxml.jackson.core.JsonGenerator; import com.fasterxml.jackson.databind.JsonMappingException; public class Demo { public static void main(String[] args) { try { JsonFactory jfactory = new JsonFactory(); /*** write to file ***/ JsonGenerator jGenerator = jfactory.createJsonGenerator(new File("c:\\user.json"), JsonEncoding.UTF8); jGenerator.writeStartObject(); // { jGenerator.writeStringField("name", "mkyong"); // "name" : "mkyong" jGenerator.writeNumberField("age", 29); // "age" : 29 jGenerator.writeFieldName("messages"); // "messages" : jGenerator.writeStartArray(); // [ jGenerator.writeString("msg 1"); // "msg 1" jGenerator.writeString("msg 2"); // "msg 2" jGenerator.writeString("msg 3"); // "msg 3" jGenerator.writeEndArray(); // ] jGenerator.writeEndObject(); // } jGenerator.close(); } catch (JsonGenerationException e) { e.printStackTrace(); } catch (JsonMappingException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } } }

          输出为:

    { "name":"mkyong", "age":29, "messages":["msg 1","msg 2","msg 3"] }

          解析JSON

    package com.jackson; import java.io.File; import java.io.IOException; import com.fasterxml.jackson.core.JsonParser; import com.fasterxml.jackson.core.JsonFactory; import com.fasterxml.jackson.core.JsonGenerationException; import com.fasterxml.jackson.core.JsonToken; import com.fasterxml.jackson.databind.JsonMappingException; public class ParseJSON { public static void main(String[] args) { try { JsonFactory jfactory = new JsonFactory(); /*** read from file ***/ JsonParser jParser = jfactory.createJsonParser(new File("c:\\user.json")); // loop until token equal to "}" while (jParser.nextToken() != JsonToken.END_OBJECT) { String fieldname = jParser.getCurrentName(); if ("name".equals(fieldname)) { //当前结点为name jParser.nextToken(); System.out.println(jParser.getText()); // 输出 mkyong } if ("age".equals(fieldname)) { // 当前结点为age // move to next, which is "name"'s value jParser.nextToken(); System.out.println(jParser.getIntValue()); // display 29 } if ("messages".equals(fieldname)) { jParser.nextToken(); while (jParser.nextToken() != JsonToken.END_ARRAY) { // display msg1, msg2, msg3 System.out.println(jParser.getText()); } } } jParser.close(); } catch (JsonGenerationException e) { e.printStackTrace(); } catch (JsonMappingException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } } }

          输出:

    mkyong 29 msg 1 msg 2 msg 3

    GSON解析

          Gson 是 Google 提供的用来在 Java 对象和 JSON 数据之间进行映射的 Java 类库。可以将一个 JSON 字符串转成一个 Java 对象,或者反过来。

          这是关于GSON的介绍,相对于传统的json解析,使用GSON能够极大的简化了解析流程。

          那么该如何使用GSON解析json数据呢?在这里分为以下几步:

          1、在eclipse环境下,将gson的jar包复制到libs中,因为这是Google提供的java类库,是不存在java自带的类库中的。

          2、获取json数据,并且分析。

          3、写出json数据对应的bean类

          4、使用gson解析

    Gson的基本用法

          Gson提供了fromJson() 和toJson() 两个直接用于解析和生成的方法,前者实现反序列化,后者实现了序列化。同时每个方法都提供了重载方法,我常用的总共有5个。

          基本数据类型的解析

    Gson gson = new Gson(); int i = gson.fromJson("100", int.class); //100 double d = gson.fromJson("\"99.99\"", double.class); //99.99 boolean b = gson.fromJson("true", boolean.class); // true String str = gson.fromJson("String", String.class); // String

    注:不知道你是否注意到了第2、3行有什么不一样没

          基本数据类型的生成

    Gson gson = new Gson(); String jsonNumber = gson.toJson(100); // 100 String jsonBoolean = gson.toJson(false); // false String jsonString = gson.toJson("String"); //"String"

          POJO类的生成与解析

    public class User { //省略其它 public String name; public int age; public String emailAddress; }

          生成JSON:

    Gson gson = new Gson(); User user = new User("怪盗kidou",24); String jsonObject = gson.toJson(user); // {"name":"怪盗kidou","age":24}

          解析JSON:

    Gson gson = new Gson(); String jsonString = "{\"name\":\"怪盗kidou\",\"age\":24}"; User user = gson.fromJson(jsonString, User.class);

          例子:

    import com.google.gson.Gson; public class GsonDemo { public static String content = "{\"name\": \"scnuyz\",\"subject\": [\"c\",\"java\",\"sql\"]}"; public static void main(String[] args) { Gson gson = new Gson(); Student student = gson.fromJson(content, Student.class); String name = student.name; System.out.println("content:\n"+content); System.out.println("name:"+name); String subject[] = student.subject; for(int i=0;i<subject.length;i++){ System.out.println("第"+(i+1)+"个subject:"+subject[i]); } Student student2 = new Student(); student2.setName("zyz"); student2.setSubject(new String[]{"a","b","c"}); String jsonObject = gson.toJson(student2); System.out.println("stu2:\n"+jsonObject); } } public class Student { public String name ; public String[] subject; public String getName() { return name; } public void setName(String name) { this.name = name; } public String[] getSubject() { return subject; } public void setSubject(String[] subject) { this.subject = subject; } }

    FastJSON案例

    package com.test; public class TestPerson { private int age; private String name; public TestPerson(){ } public TestPerson(int age,String name){ this.age=age; this.name=name; } public int getAge() { return age; } public void setAge(int age) { this.age = age; } public String getName() { return name; } public void setName(String name) { this.name = name; } } package com.test; import java.util.*; import com.alibaba.fastjson.*; public final class TestFastJson { public static void main(String[] args) { // TODO Auto-generated method stub TestPerson json = new TestPerson(19,"李明"); List<TestPerson> list = new ArrayList<TestPerson>(); list.add(json); list.add(new TestPerson(12,"张三")); //将集合或者对象序例化成JSON System.out.println(JSON.toJSON(json)); System.out.println( JSON.toJSON(list) ); //Json串反序列化成对象 TestPerson person = JSON.parseObject("{\"name\":\"李明\",\"age\":19}", TestPerson.class); System.out.printf("name:%s,age:%d\n",person.getName(),person.getAge()); String str = "[{\"name\":\"李明\",\"age\":19},{\"name\":\"张三\",\"age\":12}]"; //数组对象反序列化成集合 List<TestPerson> listPerson = JSON.parseArray(str,TestPerson.class); for(TestPerson item : listPerson){ System.out.println( item.getName() ); System.out.println( item.getAge()); } //没有对象直接解析JSON对象 JSONObject jobj = JSON.parseObject("{\"name\":\"李明\",\"age\":19}"); System.out.printf("name:%s,age:%d\n",jobj.getString("name"),jobj.getBigInteger("age")); //没有对象直接解析JSON数组 JSONArray jarr = JSON.parseArray("[{\"name\":\"李明\",\"age\":19},{\"name\":\"张三\",\"age\":12}]"); for(int i=0,len=jarr.size();i<len;i++){ JSONObject temp= jarr.getJSONObject(i); System.out.printf("name:%s,age:%d\n",temp.getString("name"),temp.getBigInteger("age")); } for(Object obj:jarr){ System.out.println(obj.toString()); } } }

          输出:

    {"name":"李明","age":19} [{"name":"李明","age":19},{"name":"张三","age":12}] name:李明,age:19 李明 19 张三 12 name:李明,age:19 name:李明,age:19 name:张三,age:12 {"name":"李明","age":19} {"name":"张三","age":12}
    转载请注明原文地址: https://ju.6miu.com/read-38159.html

    最新回复(0)