如何处理第三方API同名字段返回字符串、JSON对象两种数据类型的问题
兼容多类型返回字段的两种解决方案
方案一:修改字段类型为通用Object(改造成本最低)
直接将响应模型中response字段的类型改为Object,Jackson会自动根据返回值类型匹配反序列化结果,既可以接收字符串也可以接收对象,日志序列化时也能完整输出内容。
代码修改示例:
public class ActivationResponse { private String executionCode; private String executionMessage; // 将原ActivationResponseDetails类型改为Object private Object response; // 辅助方法:判断是否为成功响应 public boolean isSuccess() { return "0".equals(this.executionCode); } // 辅助方法:获取成功响应的详情对象 public ActivationResponseDetails getResponseDetail() { if (isSuccess() && response != null) { return new ObjectMapper().convertValue(response, ActivationResponseDetails.class); } return null; } // 辅助方法:获取失败响应的错误字符串 public String getErrorResponse() { if (!isSuccess() && response instanceof String) { return (String) response; } return null; } } // 原ActivationResponseDetails无需修改 public class ActivationResponseDetails { private String orderID; // getter/setter省略 }
方案二:自定义Jackson反序列化器(类型更安全)
如果需要统一返回类型,避免业务代码中做类型判断,可以为response字段配置自定义反序列化器,自动把两种类型的返回值映射到同一个实体类中。
步骤1:扩展详情类增加错误信息存储字段
public class ActivationResponseDetails { private String orderID; // 新增字段存储错误场景的返回字符串 private String errorMessage; // getter/setter省略 }
步骤2:编写自定义反序列化器
import com.fasterxml.jackson.core.JsonParser; 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 ResponseFieldDeserializer extends StdDeserializer<ActivationResponseDetails> { public ResponseFieldDeserializer() { super(ActivationResponseDetails.class); } @Override public ActivationResponseDetails deserialize(JsonParser jsonParser, DeserializationContext deserializationContext) throws IOException { JsonNode node = jsonParser.getCodec().readTree(jsonParser); ActivationResponseDetails result = new ActivationResponseDetails(); // 字符串类型:错误响应,存入errorMessage字段 if (node.isTextual()) { result.setErrorMessage(node.asText()); } // 对象类型:成功响应,存入orderID字段 else if (node.isObject()) { result.setOrderID(node.get("orderID").asText()); } return result; } }
步骤3:给响应字段绑定反序列化器
import com.fasterxml.jackson.databind.annotation.JsonDeserialize; public class ActivationResponse { private String executionCode; private String executionMessage; // 指定自定义反序列化器 @JsonDeserialize(using = ResponseFieldDeserializer.class) private ActivationResponseDetails response; // getter/setter省略 }
两种方案都不会丢失response字段内容,完全符合日志打印的需求,不会出现反序列化异常。
内容的提问来源于stack exchange,提问作者cmb28
相关产品推荐
相关产品推荐

