StdDeserializer用于抽象类及其子类型

时间:2014-08-26 09:59:05

标签: java json jackson

让抽象类A具有属性a和三个非抽象子类B,C和D. B没有附加属性,C包含属性c,D包含属性c和d。

我想为抽象类A继承StdDeserializer,以便能够根据要反序列化的属性的存在来决定选择哪个子类。

我之前使用Codehaus的一些杰克逊版本做到了这一点,使用以下实现工作正常:

class AbstractADeserializer extends StdDeserializer<A> {
    AbstractADeserializer () {
        super(A.class);
    }

    @Override
    public A deserialize(JsonParser jp, DeserializationContext ctxt)
            throws IOException, JsonProcessingException {
        ObjectMapper mapper = (ObjectMapper) jp.getCodec();
        ObjectNode root = (ObjectNode) mapper.readTree(jp);
        Class<? extends A> requestClass = null;

        // root.getFieldNames() is an iterator over all field names
        JsonNode cValue = root.findValue("c");
        JsonNode dValue = root.findValue("d");

        /*
         * Check for existence of required fields and choose the
         * corresponding request class.
         */
        logger.debug(Boolean.toString(c != null));
        logger.debug(Boolean.toString(d != null));

        if(c != null && d == null) {
            logger.debug("Found C");
            requestClass = C.class;
        } else if(c != null && d != null) {
            logger.debug("Found D");
            requestClass = D.class;
        } else {
            logger.debug("Found B");
            requestClass = B.class;
        }

        return mapper.readValue(root, requestClass);
    }
}

此工作正常,但从FasterXML ObjectMapper迁移到Jackson 2.4后,不允许ObjectNode作为readValue方法的参数。

当我修改要使用的代码时   return mapper.readValue(jp,requestClass); 我总是得到

    com.fasterxml.jackson.databind.JsonMappingException: No content to map due to end-of-input
     at [Source: org.apache.catalina.connector.CoyoteInputStream@1286ec89; line: 1, column: 559]
        at com.fasterxml.jackson.databind.JsonMappingException.from(JsonMappingException.java:148)
        at com.fasterxml.jackson.databind.ObjectMapper._initForReading(ObjectMapper.java:3095)
        at com.fasterxml.jackson.databind.ObjectMapper._readValue(ObjectMapper.java:3009)
        at com.fasterxml.jackson.databind.ObjectMapper.readValue(ObjectMapper.java:1637)

您认为灵活地确定给定输入的类而不需要手动反序列化对象有哪些替代方法?对我来说,克隆JsonParser以避免耗尽它的输入源看起来很复杂。

1 个答案:

答案 0 :(得分:4)

刚遇到类似的问题,对我来说,用mapper.readValue(jp, requestClass)

替换mapper.treeToValue(root, requestClass)就可以解决这个问题。