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
相关产品推荐
相关产品推荐

