初识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种:
- 迭代:对事件流(Jackson称之为Token流)的迭代
- 数据绑定:将Json数据绑定到对象
- 遍历树:构建一个树结构并使用合适的方法遍历它
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();
}
}