Jackson|Jackson 解决没有无参构造函数的反序列化问题

1. 问题 【Jackson|Jackson 解决没有无参构造函数的反序列化问题】在对外部代码或项目中明确不能提供无参构造函数的实例进行反序列化时,Jackson 会报找不到构造器的错误提示信息。那么如何在不修改代码的前提下实现反序列呢?
2. 解决方案 2.1 实现反序列化器
Response 对象没有提供无参构造函数,但是要实现反序列化功能。

@Setter @Getter public class Response { private Map headerMap; private Map apiMap; public Response(Map headerMap, Map apiMap) { this.headerMap = headerMap; this.apiMap = apiMap; } }

此时,可以通过实现 JsonDeserializer 接口,实现自定义反序列化器。
public class ResponseDeserializer extends JsonDeserializer { @Override public Response deserialize(JsonParser jsonParser, DeserializationContext deserializationContext) throws IOException, JacksonException { Map> map = jsonParser.readValueAs(Map.class); Map headerMap = map.get("headerMap"); Map apiMap = map.get("apiMap"); return new Response(headerMap, apiMap); } }

将反序列化器注册到 ObjectMapper 中:
public class ObjectMapperUtil { private static ObjectMapper objectMapper = new ObjectMapper(); static { SimpleModule simpleModule = new SimpleModule("custom"); simpleModule.addDeserializer(Response.class, new ResponseDeserializer()); objectMapper.registerModule(simpleModule); }public static ObjectMapper getObjectMapper() { return objectMapper; }/** * * @param object * @return */ public static String writeAsPrettyString(Object object) { try { return getObjectMapper().writerWithDefaultPrettyPrinter().writeValueAsString(object); } catch (JsonProcessingException e) { e.printStackTrace(); } return null; } }

针对该实现编写的测试如下:
class ResponseTest { @Test void testUseSelfDeserializeWithoutNoArgsConstructor() throws JsonProcessingException { Response response = ResponseUtil.getResponse(); String jsonStr = ObjectMapperUtil.getObjectMapper().writeValueAsString(response); System.out.println(jsonStr); response = objectMapper.readValue(jsonStr, Response.class); Assertions.assertNotNull(response); } }

2.2 通过 MIXMIN@JsonCreator机制实现
首先实现 @JsonCreator 功能的构造器:
public class ResponseMixin { @JsonCreator public ResponseMixin(@JsonProperty("headerMap")Map headerMap, @JsonProperty("apiMap")Map apiMap) { } }

编写测试,注册该 @JsonCreator
class ResponseTest { @Test void testUseMixin() throws JsonProcessingException { ObjectMapper objectMapper = new ObjectMapper(); objectMapper.addMixIn(Response.class, ResponseMixin.class); Response response = ResponseUtil.getResponse(); String jsonStr = objectMapper.writeValueAsString(response); System.out.println(jsonStr); response = objectMapper.readValue(jsonStr, Response.class); Assertions.assertNotNull(response); } }

3. 总结 上述两种方案都能实现自定义反序列化器的功能,因此在实际遇到问题时,通常采用的开源方案已经提供了支持。要善于利用已经的工具解决问题。

    推荐阅读