ToB企服应用市场:ToB评测及商务社交产业平台

标题: 轻松上手Jackjson(珍藏版) [打印本页]

作者: 王柳    时间: 2024-5-16 14:18
标题: 轻松上手Jackjson(珍藏版)
写在前面

虽然如今市面上有很多良好的json分析库,但 Spring默认采用Jackson分析Json。
本文将通过一系列通俗易懂的代码示例,带你逐步把握 Jackson 的基础用法、进阶技巧以及在实际项目中的应用场景。
一、Jackjson简介

Jackson 是当前用的比较广泛的,用来序列化和反序列化 json 的 Java 的开源框架。
什么是序列化和反序列化呢?
GitHub地址:https://github.com/FasterXML/jackson
从GitHub 看到,目前有8.8k stars,最近更新时间是2个月前。可见其更新速度照旧比较活跃的
也是json最流行的分析器之一
二、Jackjson优点

三、Jackjson模块及依赖

① Jackson库包括三个重要的模块
② 所需依赖
jackson-databind 依赖 jackson-core 和 jackson-annotations,所以可以只表现地添加jackson-databind依赖,jackson-core 和 jackson-annotations 也随之添加到 Java 项目工程中
maven
  1. <dependency>
  2.     <groupId>com.fasterxml.jackson.core</groupId>
  3.     <artifactId>jackson-core</artifactId>
  4.     <version>2.15.3</version>
  5. </dependency>
  6. <dependency>
  7.     <groupId>com.fasterxml.jackson.core</groupId>
  8.     <artifactId>jackson-annotations</artifactId>
  9.     <version>2.15.2</version>
  10. </dependency>
  11. <dependency>
  12.     <groupId>com.fasterxml.jackson.core</groupId>
  13.     <artifactId>jackson-databind</artifactId>
  14.     <version>2.15.2</version>
  15. </dependency>
复制代码
Gradle
  1. dependencies {
  2.     implementation 'com.fasterxml.jackson.core:jackson-databind:2.13.4'
  3. }
复制代码
四、快速上手

假设我们有一个简单的 User 类:
  1. @Data
  2. @ToString
  3. @AllArgsConstructor
  4. @NoArgsConstructor
  5. public class User {
  6.     private String name;
  7.     private int age;
  8. }
复制代码
4.1 Java对象转JSON字符串
  1. @Test
  2. public void testSerializationExample() throws JsonProcessingException {
  3.     User user = new User("小凡", 18);
  4.     ObjectMapper objectMapper = new ObjectMapper();
  5.     String userstr = objectMapper.writeValueAsString(user);
  6.     System.out.println(userstr);
  7. }
  8. //输出
  9. {"name":"小凡","age":18}
复制代码
4.2 JSON字符串转Java对象
  1. @Test
  2. public void testDeserializationExample() throws JsonProcessingException {
  3.     String json ="{"name":"小凡","age":18}";
  4.     ObjectMapper objectMapper = new ObjectMapper();
  5.     User user = objectMapper.readValue(json, User.class);
  6.     System.out.println(user);
  7. }
  8. //输出
  9. User(name=小凡, age=18)
复制代码
上面例子中我们我们使用了ObjectMapper 它是 Jackson 库的焦点类,负责实现 Java 对象与 JSON 文本之间的相互转换
五、Jackjson序列化API

5.1 普通Java对象序列化
  1. @Test
  2. public void testObjectToJson() throws JsonProcessingException {
  3.     User user = new User();
  4.     user.setName("小凡");
  5.     user.setAge(18);
  6.     ObjectMapper mapper = new ObjectMapper();
  7.     String userstr = mapper.writeValueAsString(user);
  8.     System.out.println(userstr);
  9. }
  10. //输出
  11. {"name":"小凡","age":18}
复制代码
5.2 复杂对象序列化

① 构造作者出版信息对象
  1. //书籍对象
  2. @Data
  3. public class Book {
  4.     private String bookName;
  5.     private String publishDate;
  6.     private String publishHouse;
  7.     private Double price;
  8. }
  9. //地址对象
  10. @Data
  11. public class Address {
  12.     private String city;
  13.     private String street;
  14. }
  15. //作者出版信息对象
  16. @Data
  17. public class PublishInfo {
  18.     private String name;
  19.     private String sex;
  20.     private Integer age;
  21.     private Address addr;
  22.     private List<Book> books;
  23. }
复制代码
② 复杂对象转JSON字符串
  1. @Test
  2. public void testComplexObjectToJson() throws JsonProcessingException {
  3.     //构造所有出版的书籍list
  4.     ArrayList<Book> books = new ArrayList<Book>();
  5.     Book book1 = new Book();
  6.     book1.setBookName("Java从入门到放弃");
  7.     book1.setPublishDate("2004-01-01");
  8.     book1.setPublishHouse("小凡出版社");
  9.     book1.setPrice(66.66);
  10.     Book book2 = new Book();
  11.     book2.setBookName("Spring从入门到入土");
  12.     book2.setPublishDate("2024-01-01");
  13.     book2.setPublishHouse("小凡出版社");
  14.     book2.setPrice(88.88);
  15.     books.add(book1);
  16.     books.add(book2);
  17.     //构造作者地址信息
  18.     Address addr = new Address();
  19.     addr.setCity("昆明");
  20.     addr.setStreet("xxx区xxx路xxx号");
  21.     //构造作者出版的所有书籍信息
  22.     PublishInfo publishInfo = new PublishInfo();
  23.     publishInfo.setName("小凡");
  24.     publishInfo.setSex("男");
  25.     publishInfo.setAge(18);
  26.     publishInfo.setAddr(addr);
  27.     publishInfo.setBooks(books);
  28.     ObjectMapper mapper = new ObjectMapper();
  29.     String json = mapper.writeValueAsString(publishInfo);
  30.     System.out.println(json);
  31. }
  32. //返回
  33. {"name":"小凡","sex":"男","age":18,"addr":{"city":"昆明","street":"xxx区xxx路xxx号"},"books":[{"bookName":"Java从入门到放弃","publishDate":"2004-01-01","publishHouse":"小凡出版社","price":66.66},{"bookName":"Spring从入门到入土","publishDate":"2024-01-01","publishHouse":"小凡出版社","price":88.88}]}
复制代码
5.3 List集合序列化
  1. @Test
  2. public void testListToJson() throws JsonProcessingException {
  3.     User user1 = new User();
  4.     user1.setName("小凡001");
  5.     user1.setAge(18);
  6.     User user2 = new User();
  7.     user2.setName("小凡002");
  8.     user2.setAge(30);
  9.     ArrayList<User> users = new ArrayList<>();
  10.     users.add(user1);
  11.     users.add(user2);
  12.     ObjectMapper mapper = new ObjectMapper();
  13.     String userstr = mapper.writeValueAsString(users);
  14.     System.out.println(userstr);
  15. }
  16. //输出
  17. [{"name":"小凡001","age":18},{"name":"小凡002","age":30}]
复制代码
5.4 Map集合序列化

  1. @Test
  2. public void testMapToJson() throws JsonProcessingException {
  3.     User user = new User();
  4.     user.setName("小凡");
  5.     user.setAge(18);
  6.     List<String> asList = Arrays.asList("抽烟", "喝酒", "烫头发");
  7.     HashMap<String, Object> map = new HashMap<>();
  8.     map.put("user", user);
  9.     map.put("hobby",asList);
  10.     ObjectMapper mapper = new ObjectMapper();
  11.     String json = mapper.writeValueAsString(map);
  12.     System.out.println(json);
  13. }
  14. //输出
  15. {"user":{"name":"小凡","age":18},"hobby":["抽烟","喝酒","烫头发"]}
复制代码
  1. @Test
  2. public void testMapToJsonSup() throws JsonProcessingException {
  3.     User user1 = new User();
  4.     user1.setName("小凡001");
  5.     user1.setAge(18);
  6.     User user2 = new User();
  7.     user2.setName("小凡002");
  8.     user2.setAge(30);
  9.     ArrayList<User> users = new ArrayList<>();
  10.     users.add(user1);
  11.     users.add(user2);
  12.     List<String> asList = Arrays.asList("抽烟", "喝酒", "烫头发");
  13.     HashMap<String, Object> map = new HashMap<>();
  14.     map.put("users", users);
  15.     map.put("hobby",asList);
  16.     map.put("name","张三");
  17.     ObjectMapper mapper = new ObjectMapper();
  18.     String json = mapper.writeValueAsString(map);
  19.     System.out.println(json);
  20. }
  21. //输出
  22. {"name":"张三","users":[{"name":"小凡001","age":18},{"name":"小凡002","age":30}],"hobby":["抽烟","喝酒","烫头发"]}
复制代码
5.5 日期处理

默认情况下,jackjson会将日期类型属性序列化成long型值(自1970年1月1日以来的毫秒数)。显然这样格式的数据不符合人类直观查看
假设我们有个Person对象
  1. @Data
  2. public class Person {
  3.     private String name;
  4.     private Date birthday;
  5. }
复制代码
① 我们先来看看默认转换的结果
  1. @Test
  2. public void testDateToJsonDefault() throws JsonProcessingException {
  3.     Person person = new Person();
  4.     person.setName("小凡");
  5.     person.setBirthday(new Date());
  6.     ObjectMapper mapper = new ObjectMapper();
  7.     String json = mapper.writeValueAsString(person);
  8.     System.out.println(json);
  9. }
  10. //输出
  11. {"name":"小凡","birthday":1712220896407}
复制代码
② 通过SimpleDateFormat 将日期格式化成人类可看格式表现
  1. @Test
  2. public void testDateToJson() throws JsonProcessingException {
  3.     Person person = new Person();
  4.     person.setName("小凡");
  5.     person.setBirthday(new Date());
  6.     ObjectMapper mapper = new ObjectMapper();
  7.     //进行一下日期转换
  8.     SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd");
  9.     mapper.setDateFormat(dateFormat);
  10.     String json = mapper.writeValueAsString(person);
  11.     System.out.println(json);
  12. }
  13. //输出  这个格式就人性化多了
  14. {"name":"小凡","birthday":"2024-04-04"}
复制代码
六、Jackjson反序列化API

Jackson通过将JSON字段的名称与Java对象中的getter和setter方法进行匹配,将JSON对象的字段映射到Java对象中的属性。
Jackson删除了getter和setter方法名称的“ get”和“ set”部门,并将其余名称的第一个字符转换为小写。
6.1 普通JSON字符串反序列化

6.1.1 JSON字符串->Java对象

注: 这里我们照旧使用前面小节中创建的User 实体类
  1. @Test
  2. public void testStrToObject() throws JsonProcessingException {
  3.     String json ="{"name":"小凡","age":18}";
  4.     ObjectMapper mapper = new ObjectMapper();
  5.     User user = mapper.readValue(json, User.class);
  6.     System.out.println(user);
  7. }
  8. //输出
  9. User(name=小凡, age=18)
复制代码
6.1.2  字符输入流-->Java对象
  1. @Test
  2. public void testReaderToObject() throws JsonProcessingException {
  3.     String json ="{"name":"小医仙","age":18}";
  4.     Reader reader = new StringReader(json);
  5.     ObjectMapper mapper = new ObjectMapper();
  6.     User user = mapper.readValue(json, User.class);
  7.     System.out.println(user);
  8. }
  9. //输出
  10. User(name=小医仙, age=18)
复制代码
6.1.3 字节输入流->Java对象

① 创建user001.json文件,文件内容如下

②将字节输入流转换为User对象
  1. @Test
  2. public void testInputStreamToObject() throws IOException {
  3.     FileInputStream inputStream = new FileInputStream("F:\\vueworkspace\\jackjson-demo\\jackjson-demo\\src\\json\\user001.json");
  4.     ObjectMapper mapper = new ObjectMapper();
  5.     User user = mapper.readValue(inputStream, User.class);
  6.     System.out.println(user);
  7.         }
  8. }
  9. //输出
  10. User(name=萧炎, age=18)
复制代码
6.1.4 JSON 文件反->Java对象

①我们准备一个user.json文件,内容如下

② 读取user.json文件中内容,并转换成User 对象
  1. @Test
  2. public void testJsonfileToObject() throws IOException {
  3.     File file = new File("F:\\vueworkspace\\jackjson-demo\\jackjson-demo\\src\\json\\user.json");
  4.     ObjectMapper mapper = new ObjectMapper();
  5.     User user = mapper.readValue(file, User.class);
  6.     System.out.println(user);
  7. }
  8. //输出
  9. User(name=萧炎, age=18)
复制代码
6.1.5 URL文件->Java对象

① 我们在网络上放一个user.json资源文件,内容如下
  1. {"name":"紫妍","age":18}
复制代码
② 通过URL(java.net.URL) 将JSON转换成User对象
  1. @Test
  2. public void testUrlToObject() throws IOException {
  3.     String url ="https://files.cnblogs.com/files/blogs/685650/user.json";
  4.     URL url1 = new URL(url);
  5.     ObjectMapper mapper = new ObjectMapper();
  6.     User user = mapper.readValue(url1, User.class);
  7.     System.out.println(user);
  8. }
  9. //输出
  10. User(name=紫妍, age=18)
复制代码
6.1.6 字节数组-> java对象
  1. @Test
  2. public void testByteToObject() throws IOException {
  3.     String json ="{"name":"韩雪","age":18}";
  4.     byte[] bytes = json.getBytes();
  5.     ObjectMapper mapper = new ObjectMapper();
  6.     User user = mapper.readValue(bytes, User.class);
  7.     System.out.println(user);
  8. }
  9. //输出
  10. User(name=韩雪, age=18)
复制代码
6.2  JSON数组字符串 反序列化

6.2.1 JSON字符串->Map集合
  1. @Test
  2. public void testJsonStrToMap() throws JsonProcessingException {
  3.     //{"name":"小凡","sex":"男","age":18}
  4.     String json ="{"name":"小凡","sex":"男","age":18}";
  5.     ObjectMapper mapper = new ObjectMapper();
  6.     Map<String, Object> map = mapper.readValue(json, new TypeReference<Map<String, Object>>() {});
  7.     System.out.println(map);
  8. }
  9. //输出
  10. {name=小凡, sex=男, age=18}
复制代码
6.2.2 JSON数组字符串->List集合
  1. @Test
  2. public void testJsonArrToList() throws JsonProcessingException {
  3.     //[{"name":"小凡001","age":18},{"name":"小凡002","age":30}]
  4.     String json ="[{"name":"小凡001","age":18},{"name":"小凡002","age":30}]";
  5.     ObjectMapper mapper = new ObjectMapper();
  6.     List<User> users = mapper.readValue(json, new TypeReference<List<User>>() {
  7.     });
  8.     System.out.println(users);
  9. }
  10. //输出
  11. [User(name=小凡001, age=18), User(name=小凡002, age=30)]
复制代码
6.2.3  JSON数组字符串->Java对象数据
  1. @Test
  2. public void testJsonArrToObjArr() throws JsonProcessingException {
  3.     //[{"name":"小凡001","age":18},{"name":"小凡002","age":30}]
  4.     String json ="[{"name":"小凡001","age":18},{"name":"小凡002","age":30}]";
  5.     ObjectMapper mapper = new ObjectMapper();
  6.     User[] users = mapper.readValue(json, User[].class);
  7.     for (User user : users) {
  8.         System.out.println(user);
  9.     }
  10. }
  11. //输出
  12. User(name=小凡001, age=18)
  13. User(name=小凡002, age=30)
复制代码
七、自界说序列化反序列化

通过自界说序列化和反序列化可以使其更加灵活多变
7.1 自界说序列化

有时候,我们不需要jackjson默认的序列化方式。例如,JSON中使用与Java对象中差异的属性名称,
或者不需要Java对象中的某个字段,这时我们就需要自界说序列化器
我们先来看看User实体对象的界说如下
  1. @Data
  2. public class User {
  3.     private String name;
  4.     private Integer age;
  5. }
复制代码
按照下面默认序列化代码,我们末了得到的JSON字符串如下
  1. @Test
  2. public void testSerializationExample() throws JsonProcessingException {
  3.     User user = new User("小凡", 18);
  4.     ObjectMapper objectMapper = new ObjectMapper();
  5.     String userstr = objectMapper.writeValueAsString(user);
  6.     System.out.println(userstr);
  7. }
  8. //输出
  9. {"name":"小凡","age":18}
复制代码
而如今的需求升级了,再不创建或修改Users实体对象的情况下,我们想要得到{"username":"小凡","userage":18} 这样的字符串,
应该怎么办呢?
这时,我们就需要自界说序列化器,就可以轻松实现,具体代码如下
  1. @Test
  2. public void testDefineSerialize() throws JsonProcessingException {
  3.     SimpleModule version1Module = new SimpleModule();
  4.     version1Module.addSerializer(User.class, new JsonSerializer<User>() {
  5.         @Override
  6.         public void serialize(User user, JsonGenerator jsonGenerator, SerializerProvider serializerProvider) throws IOException {
  7.             jsonGenerator.writeStartObject();
  8.             jsonGenerator.writeStringField("username", user.getName());
  9.             jsonGenerator.writeNumberField("userage", user.getAge());
  10.             jsonGenerator.writeEndObject();
  11.         }
  12.     });
  13.     ObjectMapper objectMapper = new ObjectMapper();
  14.     objectMapper.registerModule(version1Module);
  15.     User user = new User("小凡", 18);
  16.     String json = objectMapper.writeValueAsString(user); // 使用版本1的序列化器
  17.     System.out.println( json);
  18. }
  19. //输出
  20. {"username":"小凡","userage":18}
复制代码
7.2 自界说反序列化器

同理,反序列化也可以自界说,具体代码如下
① 自界说一个反序列化器
  1. public class UserDeserializer extends StdDeserializer<User> {
  2.     public UserDeserializer() {
  3.         this(null);
  4.     }
  5.     public UserDeserializer(Class<?> vc) {
  6.         super(vc);
  7.     }
  8.     @Override
  9.     public User deserialize(JsonParser jp, DeserializationContext ctxt)
  10.         throws IOException {
  11.         JsonNode node = jp.getCodec().readTree(jp);
  12.         String name = node.get("name").asText();
  13.         int age = (Integer) ((IntNode) node.get("age")).numberValue();
  14.         return new User(name, age);
  15.     }
  16. }
复制代码
②将JSON字符串反序列化为 User 对象
  1. @Test
  2. public void testUserDeserializer() throws JsonProcessingException {
  3.     ObjectMapper objectMapper = new ObjectMapper();
  4.     SimpleModule module = new SimpleModule();
  5.     module.addDeserializer(User.class, new UserDeserializer());
  6.     objectMapper.registerModule(module);
  7.     String json = "{"name":"小凡","age":30}";
  8.     User user = objectMapper.readValue(json, User.class);
  9.     System.out.println(user);
  10. }
  11. //输出
  12. User(name=小凡, age=30)
复制代码
八、树模型

Jackson具有内置的树模型,可用于表示JSON对象。Jackson树模型由JsonNode类表示。
在处理JSON时,我们有时并不直接关心或无法直接映射到特定的Java对象,而是需要对JSON内容进行动态、灵活的操作。
这时,树模型就派上了用场。我们可以遍历、查询、更新或合并JSON数据,而无需预先界说对应的Java类
8.1 JsonNode类型概览

JsonNode家族包括以下重要子类型:
8.2 创建与操作JsonNode实例

下面通过一些具体的代码示例,展示如何使用JackJson的树模型API来创建、操作JsonNode对象。
示例1:创建简单JsonNode
  1. @Test
  2. public void testJackJsonTreeModelExample(){
  3.     // 创建 ObjectMapper 实例
  4.     ObjectMapper mapper = new ObjectMapper();
  5.     // 创建并初始化各类型 JsonNode 实例
  6.     ObjectNode personNode = mapper.createObjectNode();
  7.     personNode.put("name", "小凡");
  8.     personNode.put("age", 18);
  9.     ArrayNode hobbiesNode = mapper.createArrayNode();
  10.     hobbiesNode.add("写代码").add("看书").add("打豆豆");
  11.     personNode.set("hobbies", hobbiesNode);
  12.     // 输出构建的 JSON 字符串
  13.     System.out.println(personNode.toString());
  14. }
  15. //输出
  16. {"name":"小凡","age":18,"hobbies":["写代码","看书","打豆豆"]}
复制代码
上述代码起首创建了一个ObjectMapper实例,它是JackJson的焦点工具类,负责序列化和反序列化工作。接着,我们创建了一个ObjectNode代表JSON对象,设置了"name"和"age"两个属性。然后创建了一个ArrayNode存储爱好列表,并将其添加到personNode中。末了,打印输出构建的JSON字符串。
示例2:从JSON字符串反序列化为JsonNode
  1. @Test
  2. public void testJackJsonTreeModelExample2() throws JsonProcessingException {
  3.     String jsonInput = "{"name":"小凡","age":18,"hobbies":["写代码","看书","打豆豆"]}";
  4.     ObjectMapper mapper = new ObjectMapper();
  5.     JsonNode rootNode = mapper.readTree(jsonInput);
  6.     System.out.println(rootNode.get("name").asText());
  7.     System.out.println(rootNode.get("age").asInt());
  8.     System.out.println(rootNode.get("hobbies").get(0).asText());
  9.     System.out.println(rootNode.get("hobbies").get(1).asText());
  10.     System.out.println(rootNode.get("hobbies").get(2).asText());
  11. }
  12. //输出
  13. 小凡
  14. 18
  15. 写代码
  16. 看书
  17. 打豆豆
复制代码
在此示例中,我们起首界说了一个JSON字符串。然后使用ObjectMapper的readTree()方法将其反序列化为JsonNode。接下来,通过调用.get(key)方法访问对象属性或数组元素,并使用.asText()、.asInt()等方法获取其值。
8.3 利用JackJson树模型进行深度查询、修改、合并等操作

上面给出的两个案例属于入门级操作,我们学会后可以接着进行一些高级操作
  1. @Test
  2. public   void testJsonManipulationExample() throws JsonProcessingException {
  3.     String JSON_STRING = "{"name":"小凡","age":18,"hobbies":["写代码","看书","打豆豆"]}";
  4.     ObjectMapper mapper = new ObjectMapper();
  5.     // 将JSON字符串转换为JsonNode对象
  6.     JsonNode rootNode = mapper.readTree(JSON_STRING);
  7.     // **深度查询**
  8.     // 查询"年龄"
  9.     int age = rootNode.get("age").asInt();
  10.     System.out.println("Age: " + age);
  11.     // 查询第一个兴趣爱好
  12.     String firstHobby = rootNode.get("hobbies").get(0).asText();
  13.     System.out.println("First hobby: " + firstHobby);
  14.     // **修改**
  15.     // 修改年龄为20
  16.     ((ObjectNode) rootNode).put("age", 20);
  17.     // 添加新的兴趣爱好:"旅行"
  18.     ((ArrayNode) rootNode.get("hobbies")).add("旅行");
  19.     // **合并**
  20.     // 假设有一个新的JSON片段要与原数据合并
  21.     String additionalJson = "{"address":"北京市","job":"程序员"}";
  22.     JsonNode additionalNode = mapper.readTree(additionalJson);
  23.     // 使用ObjectNode#setAll方法将新节点中的键值对合并到原始节点中
  24.     ((ObjectNode) rootNode).setAll((ObjectNode) additionalNode);
  25.     // 打印更新后的JSON字符串
  26.     System.out.println(mapper.writerWithDefaultPrettyPrinter().writeValueAsString(rootNode));
  27. }
  28. //输出
  29. Age: 18
  30. First hobby: 写代码
  31. {
  32.   "name" : "小凡",
  33.   "age" : 20,
  34.   "hobbies" : [ "写代码", "看书", "打豆豆", "旅行" ],
  35.   "address" : "北京市",
  36.   "job" : "程序员"
  37. }
复制代码
九、Jackson注解使用

9.1 序列化反序列化通用注解

9.1.1 @JsonIgnore

@JsonIgnore 用于在序列化或反序列化过程中忽略某个属性
界说实体类Person
  1. public class Person {
  2.     private String name;
  3.     @JsonIgnore // 添加此注解以忽略 password 字段
  4.     private String password;
  5.     // 构造器、getter/setter 方法等...
  6. }
复制代码
使用示例
  1. @Test
  2. public void testJsonIgnore() throws Exception{
  3.     Person person = new Person("小凡", "123456");
  4.     ObjectMapper mapper = new ObjectMapper();
  5.     String json = mapper.writeValueAsString(person);
  6. }
  7. //输出
  8. {
  9.   "name": "小凡"
  10. }
复制代码
具体表明
9.1.2 @JsonIgnoreProperties

与@JsonIgnore 注解相比,@JsonIgnoreProperties 用于批量指定在序列化或反序列化过程中应忽略的属性列表,特别适用于应对不明确或动态变革的输入 JSON 中可能存在但不应处理的额外字段
界说实体类Person
希望同时忽略 password 和 socialSecurityNumber 两个敏感属性
  1. @JsonIgnoreProperties({"password", "socialSecurityNumber"})
  2. public class Person {
  3.     private String name;
  4.     private String password;
  5.     private String socialSecurityNumber;
  6.     // 构造器、getter/setter 方法等...
  7. }
复制代码
使用示例
  1. @Test
  2. public void testJsonIgnoreProperties() throws Exception{
  3.     Person person = new Person("小凡", "123456","233535");
  4.     ObjectMapper mapper = new ObjectMapper();
  5.     String json = mapper.writeValueAsString(person);
  6. }
  7. //输出
  8. {
  9.   "name": "小凡"
  10. }
复制代码
具体表明
  1. {
  2.   "name": "小凡"
  3. }
复制代码
④  @JsonIgnoreProperties 还有一个额外功能
@JsonIgnoreProperties有个可选的属性 ignoreUnknown,用于控制是否忽略 JSON 中存在但 Java 类中没有对应的未知属性。若设置为 true,则在反序列化时碰到未知属性时会自动忽略,制止抛出异常
  1. @JsonIgnoreProperties(ignoreUnknown = true)
  2. public class Person {
  3.     // ...
  4. }
复制代码
9.1.3  @JsonIgnoreType

@JsonIgnoreType 注解在 Jackson 库中用于指示整个类在序列化或反序列化过程中应当被忽略。这适用于那些由于某种原因(如敏感信息、内部细节等)不需要或不应该被 JSON 化处理的类
界说CreditCardDetails 实体类
  1. // 标记该类在序列化和反序列化时应被忽略
  2. @JsonIgnoreType
  3. public class CreditCardDetails {
  4.     private String cardNumber;
  5.     private String cvv;
  6.     private String expirationDate;
  7.      // 构造器、getter/setter 方法等...
  8. }
复制代码
界说Customer 类
Customer 类,它有一个 creditCardDetails 属性引用上述 CreditCardDetails 类型的对象:
  1. public class Customer {
  2.     private String customerId;
  3.     private String name;
  4.     private CreditCardDetails creditCardDetails;
  5.     // 构造器、getter/setter 方法等...
  6. }
复制代码
使用示例
  1. public void testJsonIgnoreType() throws JsonProcessingException {
  2.     Customer customer = new Customer("CUST001", "John Doe", new CreditCardDetails("1234567890123456", "123", "2024-12"));
  3.     ObjectMapper mapper = new ObjectMapper();
  4.     String json = mapper.writeValueAsString(customer);
  5. }
  6. //输出
  7. {
  8.   "customerId": "CUST001",
  9.   "name": "John Doe"
  10. }
复制代码
具体表明
在此例中,天生的 json 字符串将不含 creditCardDetails 部门,仅包含 customerId 和 name:
  1. {
  2.   "customerId": "CUST001",
  3.   "name": "John Doe"
  4. }
复制代码
同理,在反序列化过程中,如果 JSON 数据中包含 CreditCardDetails 类型的嵌套结构,Jackson 分析时会自动忽略这部门内容,不会实行创建或填充对应的 CreditCardDetails 对象
9.1.4 @JsonAutoDetect

@JsonAutoDetect 用于自界说类的属性(包括字段和 getter/setter 方法)在序列化和反序列化过程中的可见性规则。默认情况下,Jackson 只使用 public 的字段和 public 的 getter/setter 方法。通过使用 @JsonAutoDetect,你可以根据需要调整这些规则,以适应差异类的设计和数据模型。
界说实体类 Employee
  1. @JsonAutoDetect(
  2.     fieldVisibility = JsonAutoDetect.Visibility.NONE,   // 不使用字段
  3.     getterVisibility = JsonAutoDetect.Visibility.PROTECTED_AND_PUBLIC, // 允许 protected 和 public 的 getter
  4.     setterVisibility = JsonAutoDetect.Visibility.ANY,   // 允许任意访问权限的 setter
  5.     isGetterVisibility = JsonAutoDetect.Visibility.DEFAULT,  // 默认行为(public)
  6.     creatorVisibility = JsonAutoDetect.Visibility.DEFAULT) // 默认行为(public)
  7. public class Employee {
  8.     protected String id;
  9.     String department; // package-private 字段
  10.     // 非标准命名的 getter
  11.     public String getIdentification() {
  12.         return id;
  13.     }
  14.     // 非标准命名的 setter
  15.     public void setIdentification(String id) {
  16.         this.id = id;
  17.     }
  18.     //...标准getter setter
  19. }
复制代码
使用示例
  1. @Test
  2. public  void testJsonAutoDetect() throws JsonProcessingException {
  3.     ObjectMapper mapper = new ObjectMapper();
  4.     Employee employee = new Employee();
  5.     employee.setId("E001");
  6.     employee.setDepartment("Sales");
  7.     String json = mapper.writeValueAsString(employee);
  8.     System.out.println(json);
  9. }
  10. //输出
  11. {
  12.   "identification": "E001",
  13.   "department": "Sales"
  14. }
复制代码
具体表明
9.1.5  @JsonProperty

用于指定类的属性在序列化和反序列化成 JSON 时所对应的键名
Book 实体类
假设有一个 Book 类,此中包含 title 和 yearPublished 字段。我们希望在序列化和反序列化时,将 yearPublished 字段以 publishedYear 作为 JSON 键名。可以使用 @JsonProperty 注解进行重定名:
  1. public class Book {
  2.     private String title;
  3.     @JsonProperty("publishedYear") // 重命名 yearPublished 字段为 publishedYear
  4.     private int yearPublished;
  5.     // 构造器、getter/setter 方法等...
  6. }
复制代码
使用示例:
如今创建一个 Book 对象并序列化为 JSON:
  1. public void testJsonProperty() throws Exception {
  2.     Book book = new Book();
  3.     book.setTitle("小凡编程语录");
  4.     book.setYearPublished(1951);
  5.     ObjectMapper mapper = new ObjectMapper();
  6.     String json = mapper.writeValueAsString(book);
  7.     System.out.println(json);
  8. }
  9. //输出
  10. {
  11.   "title": "小凡编程语录",
  12.   "publishedYear": 1951
  13. }
复制代码
具体表明
在本例中,@JsonProperty("publishedYear") 表明 yearPublished 字段在 JSON 中应称为 publishedYear
反序列化时,当碰到 JSON 中的 publishedYear 键时,Jackson 会知道应该将其值赋给 Book 类的 yearPublished 字段。
9.1.6  @JsonFormat

用于指定日期、时间、日期时间以及其他数值类型在序列化和反序列化为 JSON 时的格式
创建 Student 类
  1. public class Student {
  2.     // 其他属性...
  3.     // 使用 @JsonFormat 注解的 LocalDate 属性
  4.     @JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "yyyy-MM-dd")
  5.     private LocalDate birthday;
  6.     // 构造器、getter、setter 等...
  7. }
复制代码
使用示例
注:Jackson默认不支持Java 8的日期时间类型java.time.LocalDate,如果使用jdk8需要引入如下依赖.
  1. <dependency>
  2.         <groupId>com.fasterxml.jackson.datatype</groupId>
  3.         <artifactId>jackson-datatype-jsr310</artifactId>
  4.         <version>最新版本号</version>
  5. </dependency>
复制代码
除了引入以来外,还需要确保在使用Jackson进行序列化和反序列化时,注册JavaTimeModule
mapper.registerModule(new JavaTimeModule());
  1. @Test
  2. public void testJsonFormat() throws JsonProcessingException {
  3.     ObjectMapper mapper = new ObjectMapper(); // 创建 Jackson 的 ObjectMapper 实例
  4.     mapper.registerModule(new JavaTimeModule());
  5.     // 序列化示例
  6.     Student student = new Student();
  7.     student.setName("小凡");
  8.     student.setAge(18);
  9.     student.setBirthday(LocalDate.of(1990,1,1)); // 设置用户的出生日期
  10.     String json = mapper.writeValueAsString(student); // 将用户对象转换为 JSON 字符串
  11.     System.out.println(json); // 输出序列化后的 JSON 数据
  12.     // 反序列化示例
  13.     String inputJson = "{"birthday":"1990-01-01"}";
  14.     Student deserializedUser = mapper.readValue(inputJson, Student.class); // 从 JSON 字符串反序列化为 User 对象
  15.     System.out.println(deserializedUser.getBirthday()); // 输出反序列化后获得的出生日期
  16. }
  17. //输出
  18. {"name":"小凡","age":18,"birthday":"1990-01-01"}
  19. 1990-01-01
复制代码
具体表明
@JsonFormat 注解在 Jackson 中被用来精确控制日期/时间类型的属性在 JSON 序列化和反序列化过程中的格式。通过给定合适的 shape 和 pattern 参数,可以确保日期数据在 Java 类型与 JSON 文本之间准确无误地转换。
9.2 序列化注解

9.2.1 @JsonInclude

用于控制对象在序列化过程中包含哪些属性。它可以防止空或特定值的字段被序列化到JSON输出中,从而帮助您精简JSON数据结构,减少不须要的传输量或制止向客户端暴露不须要的信息
界说PersonInclude实体类
  1. @JsonInclude(JsonInclude.Include.NON_NULL)
  2. public class PersonInclude {
  3.     /**
  4.      * 姓名字段,由于未指定@JsonInclude注解,因此继承类级别的NON_NULL策略
  5.      */
  6.     private String name;
  7.     /**
  8.      * 职业字段,显式指定为仅在非空时才包含在序列化结果中
  9.      */
  10.     @JsonInclude(JsonInclude.Include.NON_EMPTY)
  11.     private String occupation;
  12.     /**
  13.      * 兴趣爱好列表,遵循类级别的NON_NULL策略
  14.      */
  15.     private List<String> hobbies;
  16.     // 构造函数、getter/setter等省略...
  17. }
复制代码
使用示例
  1. @Test
  2. public void testJsonInclude() throws JsonProcessingException {
  3.     PersonInclude personFull = new PersonInclude();
  4.     personFull.setName("小凡");
  5.     personFull.setOccupation("程序员");
  6.     personFull.setHobbies(Arrays.asList("编程","看书","打豆豆"));
  7.     PersonInclude personPartial = new PersonInclude();
  8.     personPartial.setName(null);
  9.     personPartial.setOccupation("保洁员");
  10.     ObjectMapper mapper = new ObjectMapper();
  11.     String json = mapper.writeValueAsString(personFull);
  12.     System.out.println(json);
  13.     String json1 = mapper.writeValueAsString(personPartial);
  14.     System.out.println(json1);
  15. }
  16. //输出
  17. {"name":"小凡","occupation":"程序员","hobbies":["编程","看书","打豆豆"]}
  18. {"occupation":"保洁员"}
复制代码
具体表明
9.2.2 @JsonGetter

用于告诉Jackson,应该通过调用getter方法而不是通过直接字段访问来获取某个字段值
创建PersonGetter实体类
  1. public class PersonGetter {
  2.     private String firstName;
  3.     private String lastName;
  4.     // 使用 @JsonGetter 定义一个方法,该方法将在序列化时作为 "fullName" 属性的值返回
  5.     @JsonGetter("fullName")
  6.     public String getFullName() {
  7.         return this.firstName + " " + this.lastName;
  8.     }
  9.    // 构造函数和其他常规setter/getter方法
  10. }
复制代码
使用示例
  1. @Test
  2. public void testJsonGetter() throws JsonProcessingException {
  3.     ObjectMapper mapper = new ObjectMapper(); // 创建 Jackson 的 ObjectMapper 实例
  4.     PersonGetter person = new PersonGetter("张", "小凡");// 创建一个 Person 对象
  5.     String json = mapper.writeValueAsString(person); // 将 Person 对象序列化为 JSON 字符串
  6.     System.out.println(json); // 输出序列化后的 JSON
  7. }
  8. //输出
  9. {"firstName":"张","lastName":"小凡","fullName":"张 小凡"}
复制代码
@JsonGetter 注解成功地将 getFullName() 方法的结果映射到 JSON 对象中的 "fullName" 属性。
9.2.3 @JsonAnyGetter

用于标记一个方法,获取除已知属性外的所有其他键值对。这些键值对通常存储在一个 Map 结构中,
以便将它们作为一个附加的对象进行序列化。
创建CustomData实体类
  1. @Data
  2. public class CustomData {
  3.     private final Map<String, Object> additionalProperties = new HashMap<>();
  4.     // 使用 @JsonAnyGetter 定义一个方法,该方法将在序列化时返回所有额外属性
  5.     @JsonAnyGetter
  6.     public Map<String, Object> getAdditionalProperties() {
  7.         return additionalProperties;
  8.     }
  9.     // 提供方法来添加或修改额外属性
  10.     public void addProperty(String key, Object value) {
  11.         additionalProperties.put(key, value);
  12.     }
  13. }
复制代码
使用示例
  1. @Test
  2. public void testJsonAnyGetter() throws JsonProcessingException {
  3.     ObjectMapper mapper = new ObjectMapper(); // 创建 Jackson 的 ObjectMapper 实例
  4.     CustomData data = new CustomData();
  5.     data.addProperty("key1", "value1");
  6.     data.addProperty("key2", 42);
  7.     data.addProperty("key3", "value3");
  8.     String json = mapper.writeValueAsString(data); // 将 CustomData 对象序列化为 JSON 字符串
  9.     System.out.println(json); // 输出序列化后的 JSON
  10. }
  11. //输出
  12. {"key1":"value1","key2":42,"key3":"value3"}
复制代码
@JsonAnyGetter 注解的重要作用如下:
9.2.4 @JsonPropertyOrder

用于指定类中属性在序列化为 JSON 时的排序规则
创建OrderPerson 实体类
  1. public class OrderPerson {
  2.     @JsonProperty("firstName")
  3.     private String givenName;
  4.     @JsonProperty("lastName")
  5.     private String familyName;
  6.     // 构造函数和其他常规setter/getter方法
  7. }
复制代码
使用示例
  1. @Test
  2. public void testJsonPropertyOrder() throws JsonProcessingException {
  3.     ObjectMapper mapper = new ObjectMapper(); // 创建 Jackson 的 ObjectMapper 实例
  4.     OrderPerson person = new OrderPerson("John", "Doe"); // 创建一个 OrderedPerson 对象
  5.     String json = mapper.writeValueAsString(person); // 将 OrderedPerson 对象序列化为 JSON 字符串
  6.     System.out.println(json); // 输出序列化后的 JSON
  7. }
  8. //输出
  9. {"firstName":"John","lastName":"Doe"}
复制代码
@JsonPropertyOrder 注解按照指定顺序("lastName","firstName")对 JSON 对象的属性进行了排序。
9.2.5 @JsonRawValue

用于标记一个字段或方法返回值,指示Jackson在序列化时应将其原始值视为未经转义的 JSON 字符串,并直接嵌入到输出的 JSON 文档中。纵然所标记的值包含 JSON 特殊字符(如双引号、反斜杠等),也不会对其进行转义
创建一个包含 @JsonRawValue 注解的类
  1. public class RawJsonValueExample {
  2.     private String normalProperty = "这是一个正常字符串";
  3.     // 使用 @JsonRawValue 标记 rawJsonProperty,使其内容被视为未经转义的 JSON 值
  4.     @JsonRawValue
  5.     private String rawJsonProperty = "{"key": "value", "array": [1, 2, 3]}";
  6.     // 构造函数和其他常规setter/getter方法
  7. }
复制代码
使用示例
  1. @Test
  2. public void testJsonRawValue() throws JsonProcessingException {
  3.     ObjectMapper mapper = new ObjectMapper(); // 创建 Jackson 的 ObjectMapper 实例
  4.     RawJsonValueExample example = new RawJsonValueExample(); // 创建一个 RawJsonValueExample 对象
  5.     String json = mapper.writeValueAsString(example); // 将 RawJsonValueExample 对象序列化为 JSON 字符串
  6.     System.out.println(json); // 输出序列化后的 JSON
  7. }
  8. //输出
  9. {"normalProperty":"这是一个正常字符串","rawJsonProperty":{"key": "value", "array": [1, 2, 3]}}
复制代码
rawJsonProperty 的值并未被转义,而是作为一个完整的 JSON 对象直接嵌入到父 JSON 文档中。
当您需要在 JSON 对象中嵌入另一段 JSON 文本时,使用 @JsonRawValue 可以确保这段文本以未经转义的情势出如今输出的 JSON 中,保持其原有的 JSON 结构。
9.2.6 @JsonValue

用于标记一个方法或字段,Jackson在序列化该类实例时,直接使用该方法的返回值或字段的值作为整个对象的 JSON 表示,而非按照类的通例属性进行序列化
创建JsonValueExample类
  1. public class JsonValueExample {
  2.     private LocalDate date;
  3.     private String formattedDate;
  4.     @JsonValue
  5.     public String asJsonString() {
  6.         return "{"date":"" + date.toString() + "","formatted":"" + formattedDate + ""}";
  7.     }
  8.     // 构造函数和其他常规setter/getter方法
  9. }
复制代码
使用示例
  1. @Test
  2. public void testJsonValue() throws JsonProcessingException {
  3.     ObjectMapper mapper = new ObjectMapper();
  4.     JsonValueExample example = new JsonValueExample();
  5.     example.setDate(LocalDate.of(2024,4,6));
  6.     example.setFormattedDate("yyyy-MM-dd");
  7.     String json = mapper.writeValueAsString(example);
  8.     System.out.println(json);
  9. }
  10. //输出
  11. "{"date":"2024-04-06","formatted":"yyyy-MM-dd"}"
复制代码
在 asJsonString() 方法上应用注解,指示序列化时应将该方法的返回值作为整个对象的 JSON 表达,忽略类中其他的属性
9.2.7 @JsonSerialize

于指定类、字段或方法在序列化过程中使用的自界说序列化逻辑
创建一个包含 @JsonSerialize 注解的类及其自界说序列化器
  1. public class BooleanSerializer extends JsonSerializer<Boolean> {
  2.     @Override
  3.     public void serialize(Boolean aBoolean, JsonGenerator jsonGenerator, SerializerProvider serializerProvider) throws IOException {
  4.         if(aBoolean){
  5.             jsonGenerator.writeNumber(1);
  6.         } else {
  7.             jsonGenerator.writeNumber(0);
  8.         }
  9.     }
  10. }
  11. public class PersonSerializer {
  12.     public long   personId = 0;
  13.     public String name     = "John";
  14.     @JsonSerialize(using = BooleanSerializer.class)
  15.     public boolean enabled = false;
  16.     // 构造函数和其他常规setter/getter方法
  17. }
复制代码
使用示例
  1. @Test
  2. public void testJsonSerialize() throws JsonProcessingException {
  3.     PersonSerializer person = new PersonSerializer();
  4.     person.setName("小凡");
  5.     person.setPersonId(1001);
  6.     person.setEnabled(true);
  7.     ObjectMapper mapper = new ObjectMapper();
  8.     String json = mapper.writeValueAsString(person);
  9.     System.out.println(json);
  10. }
  11. //输出
  12. {"personId":1001,"name":"小凡","enabled":1}
复制代码
通过上面代码测试我们可以看到,enabled被序列化为1
9.3 反序列化注解

9.3.1 @JsonSetter

用于标记一个方法或字段,指示 Jackson 在反序列化过程中应如何设置该属性的值
创建PersonSetter 类
  1. public class PersonSetter {
  2.     @JsonSetter("first_name")
  3.     private String firstName;
  4.     @JsonSetter("last_name")
  5.     private String lastName;
  6.   // 其他getter setter toString方法省略...
  7. }
复制代码
使用示例
  1. @Test
  2. public void testJsonSetter() throws JsonProcessingException {
  3.     String jsonNormal = "{"first_name":"张", "last_name":"小凡"}";
  4.     ObjectMapper mapper = new ObjectMapper();
  5.     PersonSetter person = mapper.readValue(jsonNormal, PersonSetter.class);
  6.     System.out.println(person);
  7. }
  8. //输出
  9. PersonSetter(firstName=张, lastName=小凡)
复制代码
@JsonSetter 注解提供了灵活的方式来定制Jackson在反序列化期间如何将JSON数据映射到Java对象的属性
9.3.2 @JsonAnySetter

用于处理反序列化过程中碰到的未知或额外的 JSON 键值对。当一个对象的JSON表示中包含无法直接映射到已声明属性的键时,这个注解可以帮助捕获并存储这些额外的数据
界说带有 @JsonAnySetter 注解的类
  1. @ToString
  2. public class CustomObject {
  3.     private String knownProperty;
  4.     private Map<String, Object> additionalProperties = new HashMap<>();
  5.     // 已知属性的setter方法
  6.     public void setKnownProperty(String knownProperty) {
  7.         this.knownProperty = knownProperty;
  8.     }
  9.     // 获取已知属性的getter方法省略...
  10.     /**
  11.      * @JsonAnySetter注解方法,用于处理反序列化过程中遇到的所有未知属性。
  12.      *
  13.      * @param key   未知属性的键
  14.      * @param value 未知属性的值
  15.      */
  16.     @JsonAnySetter
  17.     public void addAdditionalProperty(String key, Object value) {
  18.         additionalProperties.put(key, value);
  19.     }
  20.     // 提供访问额外属性的方法
  21.     public Map<String, Object> getAdditionalProperties() {
  22.         return additionalProperties;
  23.     }
  24. }
复制代码
使用示例
  1. @Test
  2. public void testJsonAnySetter() throws JsonProcessingException {
  3.     String json ="{"knownProperty":"expectedValue","extraField1":"someValue","extraField2":42,"nestedObject":{"key":"value"}}";
  4.     ObjectMapper mapper = new ObjectMapper();
  5.     CustomObject customObject = mapper.readValue(json, CustomObject.class);
  6.     System.out.println(customObject);
  7. }
  8. //输出
  9. CustomObject(knownProperty=expectedValue, additionalProperties={extraField1=someValue, nestedObject={key=value}, extraField2=42})
复制代码
@JsonAnySetter注解来应对JSON反序列化过程中可能出现的未知属性,确保所有数据都能被妥善处理和保留。这种机制特别适用于需要兼容动态或扩展性较强的JSON输入场景。
9.3.3 @JsonCreator

用于标记一个构造器、静态工厂方法或实例方法,使其成为反序列化过程中创建对象实例的入口点。这个注解帮助 Jackson 确定如何根据 JSON 数据构建相应的 Java 对象。
界说带有 @JsonCreator 注解的类
  1. public class AddressCreator {
  2.     private  String street;
  3.     private  int number;
  4.     private  String city;
  5.     // 构造器上使用@JsonCreator注解,指示Jackson使用此构造器反序列化JSON
  6.     @JsonCreator
  7.     public AddressCreator(@JsonProperty("street") String street,
  8.                    @JsonProperty("number") int number,
  9.                    @JsonProperty("city") String city) {
  10.         this.street = street;
  11.         this.number = number;
  12.         this.city = city;
  13.     }
  14.     // getter setter toString方法省略...
  15. }
复制代码
使用示例
  1. @Test
  2. public void testCreateor() throws JsonProcessingException {
  3.     String json ="{"street":"呈贡区","number":123,"city":"昆明"}";
  4.     ObjectMapper mapper = new ObjectMapper();
  5.     AddressCreator addressCreator = mapper.readValue(json, AddressCreator.class);
  6.     System.out.println(addressCreator);
  7. }
  8. //输出
  9. AddressCreator(street=呈贡区, number=123, city=昆明)
复制代码
9.3.4 @JacksonInject

用于在反序列化过程中自动注入依赖项或附加信息到目标对象。通常用于处理那些不能直接从 JSON 数据中获取、但又希望在反序列化完成后立即可用的信息
界说带有 @JacksonInject 注解的类
  1. public class UserInject {
  2.     private String name;
  3.     private String email;
  4.     // @JacksonInject注解在字段上,指示Jackson在反序列化过程中注入特定值
  5.     @JacksonInject("defaultEmail")
  6.     private String defaultEmail;
  7.     // 构造器和getter setter toString方法省略...
  8. }
复制代码
使用示例
  1. @Test
  2. public void testJacksonInject() throws JsonProcessingException {
  3.     // 设置可注入的值
  4.     InjectableValues injectables = new InjectableValues.Std().addValue("defaultEmail", "xiaofan@example.com");
  5.     // 创建ObjectMapper并配置注入值
  6.     ObjectMapper mapper = new ObjectMapper().setInjectableValues(injectables);
  7.     String json = "{"name":"小凡"}";
  8.     // 反序列化时,defaultEmail字段会被自动注入指定值
  9.     UserInject userInject = mapper.readValue(json, UserInject.class);
  10.     System.out.println("Name: " + userInject.getName());
  11.     System.out.println("Email: " + userInject.getEmail());
  12.     System.out.println("Default Email: " + userInject.getDefaultEmail());
  13. }
  14. //输出
  15. Name: 小凡
  16. Email: null
  17. Default Email: xiaofan@example.com
复制代码
@JacksonInject 注解在Jackson反序列化过程中用于引入外部依赖或默认值,使得这些信息能够在反序列化完成后立即可用
9.3.5 @JsonDeserialize

用于在反序列化过程中指定自界说的反序列化器来处理某个字段或类的特殊逻辑
自界说反序列化器
  1. public class BooleanDeserializer extends JsonDeserializer<Boolean> {
  2.     @Override
  3.     public Boolean deserialize(JsonParser jsonParser, DeserializationContext deserializationContext) throws IOException, JacksonException {
  4.         String text = jsonParser.getText();
  5.         if("0".equals(text)) {
  6.             return false;
  7.         }
  8.         return true;
  9.     }
  10. }
复制代码
@JsonDeserialize注解添加到要为其使用自界说反序列化器的字段
  1. public class PersonDeserialize {
  2.     public long    id;
  3.     public String  name;
  4.     @JsonDeserialize(using = BooleanDeserializer.class)
  5.     public boolean enabled = false;
  6.     //构造器和getter setter toString方法省略...
  7. }
复制代码
使用示例
  1. {"id":1001,"name":"小凡","enabled":1}
复制代码
  1. @Test
  2. public void testJsonDeserialize() throws JsonProcessingException {
  3.     String json ="{"id":1001,"name":"小凡","enabled":1}";
  4.     ObjectMapper mapper = new ObjectMapper();
  5.     PersonDeserialize personDeserialize = mapper.readValue(json, PersonDeserialize.class);
  6.     System.out.println(personDeserialize);
  7. }
  8. //输出
  9. PersonDeserialize(id=1001, name=小凡, enabled=true)
复制代码
我们json字符串中enabled的值是1,最终反序列化成PersonDeserialize 对象后值变成了ture
本期内容到此就结束了,希望对你有所帮助。我们下期再见 (●'◡'●)

免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。




欢迎光临 ToB企服应用市场:ToB评测及商务社交产业平台 (https://dis.qidao123.com/) Powered by Discuz! X3.4