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}




相关文章
|
存储 缓存 Java
【面试题精讲】Java包装类缓存机制
【面试题精讲】Java包装类缓存机制
|
JSON Java 数据格式
6. 二十不惑,ObjectMapper使用也不再迷惑(下)
6. 二十不惑,ObjectMapper使用也不再迷惑(下)
6. 二十不惑,ObjectMapper使用也不再迷惑(下)
|
5月前
|
XML 安全 Java
一篇文章讲明白JAVA常用的工具类
一篇文章讲明白JAVA常用的工具类
69 0
|
5月前
|
Java
深入 Java 面向对象:类的定义,竟然藏着这么多门道!
【6月更文挑战第15天】Java中的类定义是OOP的基础,它封装属性(如Student的name和age)和行为(如study())。简单的类仅触及表面,而复杂的类可模拟真实世界对象的多样性和交互。类还可通过继承扩展,如Student从Person派生,增加特有属性和行为。接口和抽象类等概念进一步增强了灵活性和可扩展性。类定义的深度和广度是构建高效、可维护代码的关键。
32 0
|
前端开发 Java 编译器
Java的第十六篇文章——枚举、反射和注解(后期再学一遍)
Java的第十六篇文章——枚举、反射和注解(后期再学一遍)
|
Java Spring 容器
SpringIOC注入三种方式灵活运用(第十四课)
SpringIOC注入三种方式灵活运用(第十四课)
99 0
|
安全 Java
【JavaSE专栏44】Java常用类Calender解析,科学处理Java日期数据
【JavaSE专栏44】Java常用类Calender解析,科学处理Java日期数据
262 0
|
存储 安全 算法
《我要进大厂》- Java基础夺命连环14问,你能坚持到第几问?(Object类 | String类)(一)
《我要进大厂》- Java基础夺命连环14问,你能坚持到第几问?(Object类 | String类)
《我要进大厂》- Java基础夺命连环14问,你能坚持到第几问?(Object类 | String类)(一)
|
缓存 安全 Java
12000+字Java反射,一起全面了解Java反射机制,为学习框架铺路
12000+字Java反射,一起全面了解Java反射机制,为学习框架铺路
113 0
12000+字Java反射,一起全面了解Java反射机制,为学习框架铺路
|
Java 编译器
《我要进大厂》- Java基础夺命连环14问,你能坚持到第几问?(Object类 | String类)(二)
《我要进大厂》- Java基础夺命连环14问,你能坚持到第几问?(Object类 | String类)
《我要进大厂》- Java基础夺命连环14问,你能坚持到第几问?(Object类 | String类)(二)