JSON学习笔记


JSON是什么,有什么用?

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

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

      对比:

  1. XML可读性较高,数据量较大;JSON可读性较低(但比自己随意定义的要好),数据量较小;
  2. 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}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值