首页 > Java > java教程 > 正文

Jackson 自定义复杂反序列化

花韻仙語
发布: 2025-09-09 17:58:15
原创
891人浏览过

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\": 123\n" +
                "  },\n" +
                "  \"second\": {\n" +
                "    \"description\": \"Second Class Description\",\n" +
                "    \"enabled\": true\n" +
                "  },\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 能够处理大多数情况,但在某些特定场景下,需要自定义反序列化器:

序列猴子开放平台
序列猴子开放平台

具有长序列、多模态、单模型、大数据等特点的超大规模语言模型

序列猴子开放平台 0
查看详情 序列猴子开放平台
  • 需要进行特殊的数据转换: 例如,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 反序列化任务。

以上就是Jackson 自定义复杂反序列化的详细内容,更多请关注php中文网其它相关文章!

最佳 Windows 性能的顶级免费优化软件
最佳 Windows 性能的顶级免费优化软件

每个人都需要一台速度更快、更稳定的 PC。随着时间的推移,垃圾文件、旧注册表数据和不必要的后台进程会占用资源并降低性能。幸运的是,许多工具可以让 Windows 保持平稳运行。

下载
来源:php中文网
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn
最新问题
开源免费商场系统广告
热门教程
更多>
最新下载
更多>
网站特效
网站源码
网站素材
前端模板
关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新 English
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送
PHP中文网APP
随时随地碎片化学习

Copyright 2014-2025 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号