Jackson的ObjectMapper介绍

「这是我参与2022首次更文挑战的第12天,活动详情查看:2022首次更文挑战」。

作者:汤圆

个人博客:javalover.cc

前言

因为JacksonSpringBootStarter自带的json库,所以对Jackson的学习还是很有必要的;

而在Jackson里,核心就是ObjectMapper,它主要是负责序列化和反序列化Java对象;

目录

  1. 添加依赖
  2. 使用ObjectMapper
  3. 异常处理

正文

1. 添加依赖

<dependency>
    <groupId>com.fasterxml.jackson.core</groupId>
    <artifactId>jackson-databind</artifactId>
    <version>2.13.1</version>
</dependency>
复制代码

不出意外的话,一般都是用最新的版本,这里我们用的2.13.1;

这个依赖里面包含了jackson-corejackson-annotations两个库,我们进到databind依赖里面,就可以看到,如下所示:

<dependencies>
    <!-- Builds on core streaming API; also needs core annotations -->
    <dependency>
        <groupId>com.fasterxml.jackson.core</groupId>
        <artifactId>jackson-annotations</artifactId>
        <!-- 06-Mar-2017, tatu: Although bom provides for dependencies, some legacy
             usage seems to benefit from actually specifying version here in case
             it is dependent on transitively
        -->
        <version>${jackson.version.annotations}</version>
    </dependency>
    <dependency>
        <groupId>com.fasterxml.jackson.core</groupId>
        <artifactId>jackson-core</artifactId>
        <version>${jackson.version.core}</version>
    </dependency>
复制代码

2. 使用ObjectMapper

ObjectMapper就是负责将对象的序列化和反序列化;

即将Java对象序列化为json字符串,和把json字符串解析为Java对象

2.1 序列化:

这里我们先定义一个Java对象User,如下所示:

@Data
public class User {

    private String username;

    private String password;

}
复制代码

然后我们创建一个User对象,并将其序列化为Json字符串:

User user = new User("admin", "123");
ObjectMapper objectMapper = new ObjectMapper();
String str = objectMapper.writeValueAsString(user);
System.out.println(str);
复制代码

输出如下:

{"username":"admin","password":"123"}
复制代码

2.2 反序列化

就是将Json字符串转为Java对象;

如果我们已知序列化时的对象类型,那么就可以直接将其解析为原有的类型;

如果不知道,也有其他的方式来解析,比如Map或者JsonNode

解析为原来的Java类型:

这里我们直接用上面打印的json字符串 来处理:

User readValue = objectMapper.readValue(str, User.class);
System.out.println(readValue);
复制代码

输出如下:

User(username=admin, password=123)	
复制代码

解析为JsonNode对象:

这里如果我们不知道Java对象的类型,可以用Jackson内置的JsonNode对象,类似map:

JsonNode jsonNode = objectMapper.readTree(str);
String username = jsonNode.get("username").asText();
String password = jsonNode.get("password").asText();
System.out.println("username:"+username+", password:"+password);
复制代码

可以看到,这个JsonNode的操作跟Map很像,但是比Map灵活;包括获取值(可以通过索引来获取)、值的转型等,这里都给你封装好了;

解析为List集合:

如果需要解析的是一个json数组字符串,则需要用到TypeReference类;

这里我们创建一个json数组,然后将其序列化;

ArrayList<User> users = new ArrayList<>();
users.add(user);
users.add(user);
String jsonArrStr = objectMapper.writeValueAsString(users);
System.out.println(jsonArrStr);

List<User> userList = objectMapper.readValue(jsonArrStr, new TypeReference<List<User>>(){});
System.out.println(userList);
复制代码

这里用到了泛型的知识,可以参考Java中的泛型 - 细节篇 - 掘金 (juejin.cn)

3. 异常处理

有时候我们在解析Json字符串时,会附带一些多余的属性,此时ObjectMapper就会报错;

下面我们给上面的Json字符串增加一个属性email,然后将其解析为User对象:

String strNew = "{\"username\":\"admin\",\"password\":\"123\", \"email\": \"xxx.mail\"}";
User user1 = objectMapper.readValue(strNew, User.class);
System.out.println(user1);
复制代码

此时运行会报错,提示如下:

image-20220209170450893

意思就是email属性无法解析,而且它还温馨提示了解决办法,就是可以将其标记为忽略属性;

下面我们就对ObjectMapper进行一个简单的配置,设置如下:解析未知的属性时是否报错,我们设置为否(默认true)

objectMapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
User user2 = objectMapper.readValue(strNew, User.class);
System.out.println(user2);
复制代码

此时运行就没问题了;

当然还有其他的很多配置,如下所示:

image-20220209170807145

总结

本篇介绍了Jackson的基本知识,包括序列化和反序列化;

还介绍了一些异常处理的例子,比如解析未知的属性时不要报错,等等;

猜你喜欢

转载自juejin.im/post/7062655222018998302