关于java:StdDeserializer用于抽象类及其子类型

StdDeserializer for abstract class and it's subtypes

假设有一个具有属性a和三个非抽象子类B,C和D的抽象类A。B没有其他属性,C包含属性c,D包含属性c和d。

我希望将StdDeserializer子类化为抽象类A,以便能够基于要反序列化的属性的存在来决定选择哪个子类。

之前,我是从Codehaus发行的Jackson版本中做到这一点的,使用以下实现可以正常工作:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
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方法的参数。

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

1
2
3
4
5
6
    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以免耗尽其输入源看起来很复杂。


只是遇到了类似的问题,对我来说,已通过用mapper.treeToValue(root, requestClass)替换mapper.readValue(jp, requestClass)来解决了所有问题