You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Java中JSON响应含"NULL"字符串导致ObjectMapper反序列化失败如何处理?

问题原因

你遇到的反序列化失败,核心是JSON结构与目标Java类不匹配:
你期望将JSON反序列化为包含value1、value2属性的Test对象,但下游返回的JSON中,Test字段对应的值是字符串"NULL",而非Test类对应的JSON对象(格式应为{"value1":"xxx", "value2":"xxx"})。Jackson尝试把字符串转换为Test实例,但Test类没有接收字符串参数的构造方法/工厂方法,因此抛出MismatchedInputException。

解决方案

以下是几种可行的处理方式,根据你的业务需求选择:

方案1:自定义反序列化器处理"NULL"字符串

创建针对Test类的反序列化器,识别到字符串"NULL"时返回空实例或null,其余情况正常反序列化对象:

public class TestDeserializer extends StdDeserializer<Test> {
    public TestDeserializer() {
        this(null);
    }

    public TestDeserializer(Class<?> vc) {
        super(vc);
    }

    @Override
    public Test deserialize(JsonParser p, DeserializationContext ctxt) throws IOException {
        JsonNode node = p.getCodec().readTree(p);
        // 判断是否为"NULL"字符串
        if (node.isTextual() && "NULL".equals(node.asText())) {
            return new Test(); // 或返回null,根据业务需求调整
        }
        // 正常反序列化Test对象
        return p.getCodec().treeToValue(node, Test.class);
    }
}

在Test类上添加注解绑定反序列化器:

@JsonDeserialize(using = TestDeserializer.class)
public class Test {
    private String value1;
    private String value2;

    // 无参构造方法(Jackson反序列化必需)
    public Test() {}

    // getter、setter方法
    public String getValue1() { return value1; }
    public void setValue1(String value1) { this.value1 = value1; }
    public String getValue2() { return value2; }
    public void setValue2(String value2) { this.value2 = value2; }
}

之后原有的反序列化代码无需修改即可正常运行。

方案2:创建外层响应类匹配JSON结构

下游返回的JSON格式是{"Test": "NULL"},对应一个包含Test字段的外层类,而非直接的Test对象。可以创建外层类来接收数据,再做后续处理:

public class TestResponse {
    @JsonProperty("Test")
    private String testValue;

    // getter、setter
    public String getTestValue() { return testValue; }
    public void setTestValue(String testValue) { this.testValue = testValue; }
}

修改反序列化逻辑,根据testValue的值处理:

ResponseEntity<String> responseEntity = getDownstreamResponse(id);
ObjectMapper mapper = new ObjectMapper();
TestResponse response = mapper.readValue(responseEntity.getBody(), TestResponse.class);

Test test;
if ("NULL".equals(response.getTestValue())) {
    test = new Test(); // 或设为null,按需调整
} else {
    // 当下游正常返回Test对象的JSON字符串时,再反序列化为Test实例
    test = mapper.readValue(response.getTestValue(), Test.class);
}

方案3:全局配置Jackson处理特殊场景(不推荐)

通过全局配置让Jackson支持字符串转对象,但这种方式会影响所有类的反序列化逻辑,仅在全局都有类似需求时使用:

ObjectMapper mapper = new ObjectMapper();
SimpleModule module = new SimpleModule();
module.addDeserializer(Test.class, new TestDeserializer());
mapper.registerModule(module);

// 原反序列化代码不变
Test test = mapper.readValue(responseEntity.getBody(), Test.class);

内容的提问来源于stack exchange,提问作者Shuaib Shaikh

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.30 04:25:07