6. 二十不惑,ObjectMapper使用也不再迷惑(上)

简介: 6. 二十不惑,ObjectMapper使用也不再迷惑(上)

前言


各位好,我是YourBatman。从本文起,终于要和Jackson的“高级”部分打交道了,也就是数据绑定jackson-databind模块。通过接触它的高级API,你会持续的发现,前面花那么多篇幅讲的core核心部分是价值连城的。毕竟村上春树也告诉过我们:人生没有无用的经历嘛。


jackson-databind包含用于Jackson数据处理器的通用 数据绑定功能和树模型。它构建在Streaming API之上,并使用Jackson注解进行配置。它就是Jackson提供的高层API,是开发者使用得最多的方式,因此重要程度可见一斑。


虽然Jackson最初的用例是JSON数据绑定,但现在它也可以用于其它数据格式,只要存在解析器和生成器实现即可。但需要注意的是:类的命名在很多地方仍旧使用了“JSON”这个词(比如JsonGenerator),尽管它与JSON格式没有实际的硬依赖关系。


小贴士:底层流式API使用的I/O进行输入输出,因此理论上是支持任何格式的



image.png


版本约定


  • 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()系列方法用于写数据(可写任何类型),也就是我们常说的序列化。


image.png


  • 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}




相关文章
|
JSON Java 数据格式
6. 二十不惑,ObjectMapper使用也不再迷惑(下)
6. 二十不惑,ObjectMapper使用也不再迷惑(下)
6. 二十不惑,ObjectMapper使用也不再迷惑(下)
|
存储 Java 编译器
【java筑基】吃透泛型(一万字长文,建议收藏)
【java筑基】吃透泛型(一万字长文,建议收藏)
|
存储 安全 算法
《我要进大厂》- Java基础夺命连环14问,你能坚持到第几问?(Object类 | String类)(一)
《我要进大厂》- Java基础夺命连环14问,你能坚持到第几问?(Object类 | String类)
《我要进大厂》- Java基础夺命连环14问,你能坚持到第几问?(Object类 | String类)(一)
开心档-软件开发入门之Java 抽象类
在面向对象的概念中,所有的对象都是通过类来描绘的,但是反过来,并不是所有的类都是用来描绘对象的,如果一个类中没有包含足够的信息来描绘一个具体的对象,这样的类就是抽象类。
|
存储 Java 数据安全/隐私保护
《我要进大厂》- Java基础夺命连环10问,你能坚持到第几问?(面向对象基础篇)
《我要进大厂》- Java基础夺命连环10问,你能坚持到第几问?(面向对象基础篇)
《我要进大厂》- Java基础夺命连环10问,你能坚持到第几问?(面向对象基础篇)
|
安全 Java 编译器
《我要进大厂》- Java基础夺命连环10问,你能坚持到第几问?(异常 | 泛型)
《我要进大厂》- Java基础夺命连环10问,你能坚持到第几问?(异常 | 泛型)
《我要进大厂》- Java基础夺命连环10问,你能坚持到第几问?(异常 | 泛型)
|
Java 编译器
《我要进大厂》- Java基础夺命连环14问,你能坚持到第几问?(Object类 | String类)(二)
《我要进大厂》- Java基础夺命连环14问,你能坚持到第几问?(Object类 | String类)
《我要进大厂》- Java基础夺命连环14问,你能坚持到第几问?(Object类 | String类)(二)
|
IDE Java 编译器
《我要进大厂》- Java基础夺命连环18问,你能坚持到第几问?(基础概念 | 基本语法 | 基本数据类型)(二)
《我要进大厂》- Java基础夺命连环18问,你能坚持到第几问?(基础概念 | 基本语法 | 基本数据类型)
《我要进大厂》- Java基础夺命连环18问,你能坚持到第几问?(基础概念 | 基本语法 | 基本数据类型)(二)
|
存储 缓存 Java
《我要进大厂》- Java基础夺命连环18问,你能坚持到第几问?(基础概念 | 基本语法 | 基本数据类型)(三)
《我要进大厂》- Java基础夺命连环18问,你能坚持到第几问?(基础概念 | 基本语法 | 基本数据类型)
《我要进大厂》- Java基础夺命连环18问,你能坚持到第几问?(基础概念 | 基本语法 | 基本数据类型)(三)
|
Rust Oracle Java
《我要进大厂》- Java基础夺命连环18问,你能坚持到第几问?(基础概念 | 基本语法 | 基本数据类型)(一)
《我要进大厂》- Java基础夺命连环18问,你能坚持到第几问?(基础概念 | 基本语法 | 基本数据类型)
《我要进大厂》- Java基础夺命连环18问,你能坚持到第几问?(基础概念 | 基本语法 | 基本数据类型)(一)