Jackson的ObjectMapper介绍
作者:汤圆
个人博客:javalover.cc
前言
因为Jackson
是SpringBootStarter
自带的json
库,所以对Jackson
的学习还是很有必要的;
而在Jackson里,核心就是ObjectMapper
,它主要是负责序列化和反序列化Java对象;
目录
添加依赖
使用ObjectMapper
异常处理
正文
1. 添加依赖
<dependency> <groupId>com.fasterxml.jackson.core</groupId> <artifactId>jackson-databind</artifactId> <version>2.13.1</version> </dependency> 复制代码
不出意外的话,一般都是用最新的版本,这里我们用的2.13.1;
这个依赖里面包含了jackson-core
和jackson-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); 复制代码
此时运行会报错,提示如下:
意思就是email属性无法解析,而且它还温馨提示了解决办法,就是可以将其标记为忽略属性;
下面我们就对ObjectMapper进行一个简单的配置,设置如下:解析未知的属性时是否报错,我们设置为否(默认true)
objectMapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false); User user2 = objectMapper.readValue(strNew, User.class); System.out.println(user2); 复制代码
此时运行就没问题了;
当然还有其他的很多配置,如下所示:
总结
本篇介绍了Jackson的基本知识,包括序列化和反序列化;
还介绍了一些异常处理的例子,比如解析未知的属性时不要报错,等等;
作者:汤圆学Java
链接:https://juejin.cn/post/7062655222018998302