关于java:Jackson-解决没有无参构造函数的反序列化问题

3次阅读

共计 2427 个字符,预计需要花费 7 分钟才能阅读完成。

1. 问题

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

2. 解决方案

2.1 实现反序列化器

Response 对象没有提供无参构造函数,然而要实现反序列化性能。

@Setter
@Getter
public 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. 总结

上述两种计划都能实现自定义反序列化器的性能,因而在理论遇到问题时,通常采纳的开源计划曾经提供了反对。要长于利用曾经的工具解决问题。

正文完
 0