boxmoe_header_banner_img

Hello! 欢迎来到悠悠畅享网!

文章导读

Jackson 自定义复杂反序列化


avatar
作者 2025年9月9日 9

Jackson 自定义复杂反序列化

本文旨在解决使用 Jackson 进行复杂 JSON 反序列化时,如何避免手动映射所有字段的问题。通过利用 ObjectMapper 的 readValue 方法,结合自定义反序列化器处理特定字段,可以实现高效、简洁的反序列化过程,尤其适用于包含多个嵌套类的复杂 json 结构。文章将提供示例代码,并讨论在何种情况下需要自定义反序列化器。

在处理复杂的 JSON 结构时,Jackson 提供了强大的反序列化能力。对于包含多个嵌套类的情况,通常不需要手动映射每个字段。ObjectMapper 的 readValue 方法可以自动将 JSON 数据映射到对应的 Java 对象

使用 ObjectMapper 进行自动反序列化

最简单的方式是直接使用 ObjectMapper 的 readValue 方法。 假设我们有以下类结构:

public class TestClass {     public Class1 first;     public Class2 second;     public Class10 ten;      // Getters and setters     public Class1 getFirst() {         return first;     }      public void setFirst(Class1 first) {         this.first = first;     }      public Class2 getSecond() {         return second;     }      public void setSecond(Class2 second) {         this.second = second;     }      public Class10 getTen() {         return ten;     }      public void setTen(Class10 ten) {         this.ten = ten;     } }  public class Class1 {     public String name;     public int id;      // Getters and setters     public String getName() {         return name;     }      public void setName(String name) {         this.name = name;     }      public int getId() {         return id;     }      public void setId(int id) {         this.id = id;     } }  public class Class2 {     public String description;     public boolean enabled;      // Getters and setters     public String getDescription() {         return description;     }      public void setDescription(String description) {         this.description = description;     }      public boolean isEnabled() {         return enabled;     }      public void setEnabled(boolean enabled) {         this.enabled = enabled;     } }  public class Class10 {     public String field1;      // Getters and setters     public String getField1() {         return field1;     }      public void setField1(String field1) {         this.field1 = field1;     } }

以及对应的 JSON 字符串

{   "first": {     "name": "First Class",     "id": 123   },   "second": {     "description": "Second Class Description",     "enabled": true   },   "ten": {     "field1": "Field 1 Value"   } }

可以使用以下代码将其反序列化为 TestClass 对象:

import com.fasterxml.jackson.databind.ObjectMapper; import java.io.IOException;  public class Main {     public static void main(String[] args) {         String json = "{n" +                 "  "first": {n" +                 "    "name": "First Class",n" +                 "    "id": 123n" +                 "  },n" +                 "  "second": {n" +                 "    "description": "Second Class Description",n" +                 "    "enabled": truen" +                 "  },n" +                 "  "ten": {n" +                 "    "field1": "Field 1 Value"n" +                 "  }n" +                 "}";          ObjectMapper objectMapper = new ObjectMapper();         try {             TestClass result = objectMapper.readValue(json, TestClass.class);              System.out.println("First Name: " + result.getFirst().getName());             System.out.println("Second Description: " + result.getSecond().getDescription());             System.out.println("Ten Field1: " + result.getTen().getField1());          } catch (IOException e) {             e.printStackTrace();         }     } }

这段代码会自动将 JSON 字符串解析为 TestClass 对象,并填充其内部的 Class1、Class2 和 Class10 实例。

何时需要自定义反序列化器

虽然 ObjectMapper 能够处理大多数情况,但在某些特定场景下,需要自定义反序列化器:

Jackson 自定义复杂反序列化

Fotor AI Image Upscaler

Fotor推出的AI图片放大工具

Jackson 自定义复杂反序列化48

查看详情 Jackson 自定义复杂反序列化

  • 需要进行特殊的数据转换: 例如,JSON 中的某个字段需要进行格式转换或计算后才能赋值给 Java 对象的属性。
  • JSON 结构与 Java 对象结构不完全匹配: 例如,JSON 中的某些字段需要映射到多个 Java 对象的属性,或者 Java 对象中的某些属性需要从多个 JSON 字段获取数据。
  • 需要处理异常情况: 例如,JSON 中缺少某个字段,或者某个字段的值不合法,需要进行特殊处理。

自定义反序列化器示例

假设我们需要对 Class10 进行自定义反序列化,例如,我们需要将 JSON 中的 field1 字段的值转换为大写:

首先,创建一个自定义的反序列化器:

import com.fasterxml.jackson.core.JsonParser; import com.fasterxml.jackson.core.JsonProcessingException; import com.fasterxml.jackson.databind.DeserializationContext; import com.fasterxml.jackson.databind.Jsonnode; import com.fasterxml.jackson.databind.deser.std.StdDeserializer; import java.io.IOException;  public class Class10Deserializer extends StdDeserializer<Class10> {      public Class10Deserializer() {         this(null);     }      public Class10Deserializer(Class<?> vc) {         super(vc);     }      @Override     public Class10 deserialize(JsonParser jp, DeserializationContext ctxt)             throws IOException, JsonProcessingException {         JsonNode node = jp.getCodec().readTree(jp);         String field1 = node.get("field1").asText().toUpperCase();          Class10 class10 = new Class10();         class10.setField1(field1);         return class10;     } }

然后,在 TestClass 中使用 @JsonDeserialize 注解指定使用自定义的反序列化器:

import com.fasterxml.jackson.databind.annotation.JsonDeserialize;  public class TestClass {     public Class1 first;     public Class2 second;      @JsonDeserialize(using = Class10Deserializer.class)     public Class10 ten;      // Getters and setters     public Class1 getFirst() {         return first;     }      public void setFirst(Class1 first) {         this.first = first;     }      public Class2 getSecond() {         return second;     }      public void setSecond(Class2 second) {         this.second = second;     }      public Class10 getTen() {         return ten;     }      public void setTen(Class10 ten) {         this.ten = ten;     } }

现在,再次运行上面的 Main 类,会发现 Class10 的 field1 字段的值变成了大写。

注意事项

  • 确保 Java 类的属性名称与 JSON 字段名称一致,或者使用 @JsonProperty 注解进行映射。
  • 如果 JSON 字符串的结构与 Java 类的结构不一致,可能会导致反序列化失败。
  • 自定义反序列化器可以灵活地处理各种复杂的反序列化场景,但也会增加代码的复杂性。

总结

对于大多数复杂的 JSON 反序列化场景,ObjectMapper 的 readValue 方法已经足够强大。只有在需要进行特殊的数据转换、处理 JSON 结构与 Java 对象结构不匹配的情况、或者处理异常情况时,才需要自定义反序列化器。通过合理地使用 ObjectMapper 和自定义反序列化器,可以高效、简洁地完成 JSON 反序列化任务。



评论(已关闭)

评论已关闭