写点什么

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

作者:TRAMP
  • 2022 年 5 月 05 日
  • 本文字数:1636 字

    阅读完需:约 5 分钟

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

1. 问题

在对外部代码或项目中明确不能提供无参构造函数的实例进行反序列化时,Jackson 会报找不到构造器的错误提示信息。那么如何在不修改代码的前提下实现反序列呢?

2. 解决方案

2.1 实现反序列化器

Response 对象没有提供无参构造函数,但是要实现反序列化功能。


@Setter@Getterpublic class Response {    private Map<String, String> headerMap;    private Map<String, String> apiMap;
public Response(Map<String, String> headerMap, Map<String, String> apiMap) { this.headerMap = headerMap; this.apiMap = apiMap; }}
复制代码


此时,可以通过实现 JsonDeserializer<Response> 接口,实现自定义反序列化器。


public class ResponseDeserializer extends JsonDeserializer<Response> {    @Override    public Response deserialize(JsonParser jsonParser, DeserializationContext deserializationContext) throws IOException, JacksonException {        Map<String, Map<String, String>> map = jsonParser.readValueAs(Map.class);        Map<String, String> headerMap = map.get("headerMap");        Map<String, String> 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<String, String> headerMap,                         @JsonProperty("apiMap")Map<String, String> 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. 总结

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

发布于: 刚刚阅读数: 4
用户头像

TRAMP

关注

不随黄叶舞秋风。 2019.07.22 加入

热爱生活,热爱工作。致力于写出整洁的代码。

评论

发布
暂无评论
Jackson 解决没有无参构造函数的反序列化问题_Jackson_TRAMP_InfoQ写作社区