前言
各位好,我是YourBatman。从本文起,终于要和Jackson的“高级”部分打交道了,也就是数据绑定jackson-databind模块。通过接触它的高级API,你会持续的发现,前面花那么多篇幅讲的core核心部分是价值连城的。毕竟村上春树也告诉过我们:人生没有无用的经历嘛。
jackson-databind包含用于Jackson数据处理器的通用 数据绑定功能和树模型。它构建在Streaming API之上,并使用Jackson注解进行配置。它就是Jackson提供的高层API,是开发者使用得最多的方式,因此重要程度可见一斑。
虽然Jackson最初的用例是JSON数据绑定,但现在它也可以用于其它数据格式,只要存在解析器和生成器实现即可。但需要注意的是:类的命名在很多地方仍旧使用了“JSON”这个词(比如JsonGenerator),尽管它与JSON格式没有实际的硬依赖关系。
小贴士:底层流式API使用的I/O进行输入输出,因此理论上是支持任何格式的
版本约定
- Jackson版本:
2.11.0
- Spring Framework版本:
5.2.6.RELEASE
- Spring Boot版本:
2.3.0.RELEASE
从本文开始,新增导包:
<dependency> <groupId>com.fasterxml.jackson.core</groupId> <artifactId>jackson-databind</artifactId> </dependency>
Tips:jackson-databind模块它强依赖于jackson-core和jackson-annotations,只需要导入此包,另外两个它自动会帮带进来。
这里需要说明几句:我们知道core包中还有个jackson-annotations,难道不讲了吗?其实不是,是因为单独讲jackson-annotations并无意义,毕竟注解还得靠数据绑定模块来解析,所以先搞定这个后再杀回去。
✍正文
据我了解,很多小伙伴对Jackson的了解起源于ObjectMapper,止于ObjectMapper。那行,作为接触它的第一篇文章咱们就轻松点,以应用为主来整体的认识它。
功能介绍
ObjectMapper是jackson-databind模块最为重要的一个类,它完成了coder对数据绑定的几乎所有功能。它是面向用户的高层API,底层依赖于Streaming API来实现读/写。ObjectMapper主要提供的功能点如下:
- 它提供读取和写入JSON的功能(最重要的功能)
- 普通POJO的序列化/反序列化
- JSON树模型的读/写
- 它可以被高度定制,以使用不同风格的JSON内容
- 使用Feature进行定制
- 使用可插拔com.fasterxml.jackson.databind.Module模块来扩展/丰富功能
- 它还支持更高级的对象概念:比如多态泛型、对象标识
- 它还充当了更为高级(更强大)的API:ObjectReader和ObjectWriter的工厂
- ObjectReader和ObjectWriter底层亦是依赖于Streaming API实现读写
尽管绝大部分的读/写API都通过ObjectMapper暴露出去了,但有些功能函数还是只放在了ObjectReader/ObjectWriter里,比如对于读/写 长序列 的能力你只能通过ObjectReader#readValues(InputStream) / ObjectWriter#writeValues(OutputStream)去处理,这是设计者有意为之,毕竟这种case很少很少,没必要和常用的凑合在一起嘛。
数据绑定
数据绑定分为简单数据绑定和完全数据绑定:
- 简单数据绑定:比如绑定int类型、List、Map等…
@Test public void test1() throws JsonProcessingException { ObjectMapper objectMapper = new ObjectMapper(); // 绑定简单类型 和 Map类型 Integer age = objectMapper.readValue("1", int.class); Map map = objectMapper.readValue("{\"name\": \"YourBatman\"}", Map.class); System.out.println(age); System.out.println(map); }
运行程序,输出:
1 {name=YourBatman}
- 完全数据绑定:绑定到任意的Java Bean对象…
准备一个POJO:
@Data @NoArgsConstructor @AllArgsConstructor public class Person { private String name; private Integer age; }
绑定数据到POJO:
@Test public void test2() throws JsonProcessingException { ObjectMapper objectMapper = new ObjectMapper(); Person person = objectMapper.readValue("{\"name\": \"YourBatman\", \"age\": 18}", Person.class); System.out.println(person); }
运行程序,输出:
Person(name=YourBatman, age=18)
ObjectMapper的使用
在应用及开发中,ObjectMapper绝对是最常使用的,也是你使用Jackson的入口,本文就列列它的那些使用场景。
小贴士:树模型会单独成文介绍,体现出它的重要性
写(序列化)
提供writeValue()系列方法用于写数据(可写任何类型),也就是我们常说的序列化。
- writeValue(File resultFile, Object value):写到目标文件里
- writeValue(OutputStream out, Object value):写到输出流
- String writeValueAsString(Object value):写成字符串形式,此方法最为常用
- writeValueAsBytes(Object value):写成字节数组byte[]
@Test public void test3() throws JsonProcessingException { ObjectMapper objectMapper = new ObjectMapper(); System.out.println("----------写简单类型----------"); System.out.println(objectMapper.writeValueAsString(18)); System.out.println(objectMapper.writeValueAsString("YourBatman")); System.out.println("----------写集合类型----------"); System.out.println(objectMapper.writeValueAsString(Arrays.asList(1, 2, 3))); System.out.println(objectMapper.writeValueAsString(new HashMap<String, String>() {{ put("zhName", "A哥"); put("enName", "YourBatman"); }})); System.out.println("----------写POJO----------"); System.out.println(objectMapper.writeValueAsString(new Person("A哥", 18))); }
运行程序,输出:
----------写简单类型---------- 18 "YourBatman" ----------写集合类型---------- [1,2,3] {"zhName":"A哥","enName":"YourBatman"} ----------写POJO---------- {"name":"A哥","age":18}