Bootstrap

Jackson学习笔记(一)Jackson解析Json

初识Jackson

导入jar文件:

jackson-annotations-2.9.9.jar
jackson-core-2.9.9.jar
jackson-databind-2.9.9.jar

一、Jackson简介

1、Jackson

Jackson是一个简单基于Java应用库,Jackson可以轻松的将Java对象转换成json对象和xml文档,同样也可以将json、xml转换成Java对象。Jackson所依赖的jar包较少,简单易用并且性能也要相对高些,并且Jackson社区相对比较活跃,更新速度也比较快。

Jackson不仅支持流式处理json,还支持数据绑定(POJO和JSON之间的相互转化),甚至还拓展了很多其他第三方库所支持的数据格式。

2、Jackson的三个核心模块:

Jackson-core:定义了低级的流式API,包括了JSON处理细节。

Jackson-annotations:包含了Jackson的注解。

Jackson-databind:实现了对象和JSON之间的转换,这个包依赖上面两个包。

3、如何解析JSON:

尽管有很多种拆分JSON并解析的方法,但是可以归纳成3种:

  1. 迭代:对事件流(Jackson称之为Token流)的迭代
  2. 数据绑定:将Json数据绑定到对象
  3. 遍历树:构建一个树结构并使用合适的方法遍历它

4、对应的Java的API:

  • SAX和Stax。这个提供了一些基本的API来遍历事件流。其中,SAX是主动把event推给你(push),Stax是让你可以主动遍历这个事件流(pull)。一个是push,一个是pull,但是事件流都是一样的,只是表现方式不同。提供事件callback的SAX,主动遍历event的Stax,还有一个是Stax Cursor API(游标)。
  • JAXB是数据绑定的标准;虽然有n + 1个替代品(Jibx,XMLBeans,Castor等等),但它们都是这样做的:将(Java)对象转换为xml,反之亦然,其中一些方便而有效,另一些则不如此。
  • DOM是“最标准的”API,它定义了树结构; 但是与数据绑定一样,还有多种(更好的)替代方案(XOM,JDOM,DOM4j)。您可以逐节点遍历它,也可以使用XPath。

虽然上面说的都是XML的,但是我们讨论的是JSON啊!事实证明,格式不重要,重要的是这种解析的思想。

5、对应了Jackson提供的三个类:

  • 核心包(jackson-core)包含JsonParser和JsonGenerator,它们允许迭代令牌(Jackson喜欢说成令牌token,而不是事件event)。
  • ObjectMapper实现了数据绑定功能:JSON和Object之间的相互转换。
  • TreeMapper是把JSON字符串构造成一个树,其中包含了节点(JsonNode)和子节点(JsonNode)。

二、Java对象转Json(ObjectMapper.writeValue())

POJO类:

package main.java.StuJackson;

public class Student {
    private String id;
    private String name;
    private String gender;
    private String phone;

    public Student() {}

    public Student(String id, String name, String gender, String phone) {
        this.id = id;
        this.name = name;
        this.gender = gender;
        this.phone = phone;
    }

    //省略getter和setter

    @Override
    public String toString() {
        return "Student{" +
                "id='" + id + '\'' +
                ", name='" + name + '\'' +
                ", gender='" + gender + '\'' +
                ", phone='" + phone + '\'' +
                '}';
    }
}

 jackson中最重要的类为ObjectMapper,文档中的注释为可重用,可共享的。应该是线程安全的类。功能为实体类变为json和把json变为实体类,实体类变为json,ObjectMapper对象只把public的类成员变量或者有get方法的变量写为json串(set方法可以没有)。

注意:

把POJO对象转为json时,Jackson只会把那些拥有getter方法的属性或者声明为public的字段序列化,否则不会被该字段不会被序列化。

1、将POJO转成json格式的字符串

    @Test
    public void TestJOPO2Json1(){
        //创建ObjectMapper
        ObjectMapper mapper = new ObjectMapper();
        Student student1 = new Student("001","Jack","Male","18765456543");
        try {
            //将对象写入json字符串
            String stringPOJOJson = mapper.writeValueAsString(student1);
            System.out.println(stringPOJOJson);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

2、将POJO写入json文件

    @Test
    public void TestJOPO2Json2(){
        //创建ObjectMapper
        ObjectMapper mapper = new ObjectMapper();
        Student student1 = new Student("001","Jack","Male","18765456543");
        try {
            //将对象写入json文件
            mapper.writeValue(new File("json/jack.json"),student1);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

3、将集合对象写入json文件

    @Test
    public void TestJOPO2Json3(){
        //创建ObjectMapper
        ObjectMapper mapper = new ObjectMapper();

        Student student2 = new Student("002","Tom","Male","18765466643");
        Student student3 = new Student("003","JackSon","Male","18765477743");
        List<Student> students = new ArrayList<>();
        students.add(student2);
        students.add(student3);

        //将集合对象写入json文件
        try {
            mapper.writeValue(new File("json/students.json"),students);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

Java中的集合,在json中对应的数据结果是数组,当然,Java中的数组也对应Json中的数组。

三、Json转Java对象(ObjectMapper.readValue())

 如果接受类型和json文件中的类型不一致,会出现输入不匹配异常,提示我们某个对象的实例不能被反序列化。

com.fasterxml.jackson.databind.exc.MismatchedInputException: 
Cannot deserialize instance of `main.StuJackson.TestPOJO2Json.Student` out of START_ARRAY token

注意:

如果json中的对象中字段类型和POJO中的类型不匹配,或者数目多于POJO中的字段数目,均不反序列化成功。保证某个字段拥有getter和setter方法中的一个,或者该字段为公有类型的,该字段才能被反序列化成功。

1、将json格式的String字符串转为POJO对象

    @Test
    public void TestJson2JOPO1(){
        //Json字符串转POJO
        ObjectMapper mapper = new ObjectMapper();
        String JackJson = "{\"id\":\"001\",\"name\":\"Jack\",\"gender\":\"Male\",\"phone\":\"18765456543\"}";
        try {
            Student Jack = mapper.readValue(JackJson,Student.class);
            System.out.println(Jack.toString());
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

2、将json文件转成POJO对象

    @Test
    public void TestJson2JOPO2(){
        //Json文件转POJO
        ObjectMapper mapper = new ObjectMapper();
        try {
            Student Jack = mapper.readValue(new File("json/jack.json"),Student.class);
            System.out.println(Jack.toString());
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

3、将数组类型的json文件转为List集合

注意:

TypeReference,该类在 com.fasterxml.jackson.core.type.TypeReference 包下,不要导错包。

    @Test
    public void TestJson2JOPO3(){
        //Json数组文件转List集合
        ObjectMapper mapper = new ObjectMapper();
        try {
            List<Student> students = mapper.readValue(new File("json/students.json"), new TypeReference<ArrayList<Student>>(){});
            for (Student student : students) {
                System.out.println(student.toString());
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

 

;