目录
JSON
简述
JSON
对于开发者并不陌生,如今的 WEB
服务、移动应用、甚至物联网大多都是以 JSON
作为数据交换的格式。学习 JSON
格式的操作工具对开发者来说是必不可少的。这篇文章将介绍如何使用 Jackson
开源工具库对 JSON
进行常见操作
JSON
是 JavaScript Object Notation
的缩写,JSON
是一种基于文本的格式,可以把它理解为是一个结构化的数据,这个结构化数据中可以包含键值映射、嵌套对象以及数组等信息
{
"array": [
1,
2,
3
],
"boolean": true,
"color": "gold",
"null": null,
"number": 123,
"object": {
"a": "b",
"c": "d"
},
"string": "www.wdbyte.com"
}
Jackson
介绍
Jackson
和 FastJson
一样,是一个 Java
语言编写的,可以进行 JSON
处理的开源工具库,Jackson
的使用非常广泛,Spring
框架默认使用 Jackson
进行 JSON
处理
Jackson
有三个核心包,分别是 Streaming、Databid、Annotations
,通过这些包可以方便的对 JSON
进行操作
Streaming[1]
在jackson-core
模块。定义了一些流处理相关的API
以及特定的JSON
实现Annotations[2]
在jackson-annotations
模块,包含了Jackson
中的注解Databind[3]
在jackson-databind
模块, 在Streaming
包的基础上实现了数据绑定,依赖于Streaming
和Annotations
包
得益于 Jackson
高扩展性的设计,有很多常见的文本格式以及工具都有对 Jackson
的相应适配,如 CSV、XML、YAML
等
Jackson
的 Maven
依赖
在使用 Jackson
时,大多数情况下我们只需要添加 jackson-databind
依赖项,就可以使用 Jackson
功能了,它依赖了下面两个包
com.fasterxml.jackson.core:jackson-annotations
com.fasterxml.jackson.core:jackson-core
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>2.13.3</version>
</dependency>
为了方便这篇文章后续的代码演示,我们同时引入 Junit
进行单元测试和 Lombok
以减少 Get/Set
的代码编写
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter</artifactId>
<version>5.8.2</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.18.22</version>
</dependency>
ObjectMapper
对象映射器
ObjectMapper
是 Jackson
库中最常用的一个类,使用它可以进行 Java
对象和 JSON
字符串之间快速转换。如果你用过 FastJson
,那么 Jackson
中的 ObjectMapper
就如同 FastJson
中的 JSON
类
这个类中有一些常用的方法
readValue()
方法可以进行JSON
的反序列化操作,比如可以将字符串、文件流、字节流、字节数组等将常见的内容转换成Java
对象writeValue()
方法可以进行JSON
的序列化操作,可以将Java
对象转换成JSON
字符串
大多数情况下,ObjectMapper
的工作原理是通过 Java Bean
对象的 Get/Set
方法进行转换时映射的,所以正确编写 Java
对象的 Get/Set
方法尤为重要,不过 ObjectMapper
也提供了诸多配置,比如可以通过配置或者注解的形式对 Java
对象和 JSON
字符串之间的转换过程进行自定义。这些在下面部分都会介绍到
Jackson JSON
的基本操作
Jackson
作为一个 Java
中的 JSON
工具库,处理 JSON
字符串和 Java
对象是它最基本最常用的功能,下面通过一些例子来演示其中的用法
Jackson JSON
的序列化
编写一个 Person
类,定义三个属性,名称、年龄以及技能
@Data
public class Person {
private String name;
private Integer age;
private List<String> skillList;
}
将 Java
对象转换成 JSON
字符串
public class PersonTest {
ObjectMapper objectMapper = new ObjectMapper();
@Test
void pojoToJsonString() throws JsonProcessingException {
Person person = new Person();
person.setName("aLng");
person.setAge(27);
person.setSkillList(Arrays.asList("java", "c++"));
String json = objectMapper.writeValueAsString(person);
System.out.println(json);
String expectedJson = "{\"name\":\"aLng\",\"age\":27,\"skillList\":[\"java\",\"c++\"]}";
Assertions.assertEquals(json, expectedJson);
}
}
输出的 JSON
字符串
{
"name":"aLng","age":27,"skillList":["java","c++"]}
Jackson
甚至可以直接把序列化后的 JSON
字符串写入文件或者读取成字节数组
mapper.writeValue(new File("result.json"), myResultObject);
// 或者
byte[] jsonBytes = mapper.writeValueAsBytes(myResultObject);
// 或者
String jsonString = mapper.writeValueAsString(myResultObject);
Jackson JSON
的反序列化
public class PersonTest {
ObjectMapper objectMapper = new ObjectMapper();
@Test
void jsonStringToPojo() throws JsonProcessingException {
String expectedJson = "{\"name\":\"aLang\",\"age\":27,\"skillList\":[\"java\",\"c++\"]}";
Person person = objectMapper.readValue(expectedJson, Person.class);
System.out.println(person);
Assertions.assertEquals(person.getName(), "aLang");
Assertions.assertEquals(person.getSkillList().toString(), "[java, c++]"