反序列化可以是对象或布尔值的数据

时间:2017-07-23 15:26:34

标签: jaxb jackson

我使用具有以下依赖关系的maven和jersey

    <dependency>
        <groupId>org.glassfish.jersey.core</groupId>
        <artifactId>jersey-client</artifactId>
        <version>2.25</version>
    </dependency>
    <dependency>
        <groupId>org.glassfish.jersey.media</groupId>
        <artifactId>jersey-media-json-jackson</artifactId>
        <version>2.25</version>
    </dependency>
    <dependency>
        <groupId>org.jvnet.jaxb2_commons</groupId>
        <artifactId>jaxb2-basics-annotate</artifactId>
        <version>1.0.1</version>
    </dependency>
    <dependency>
        <groupId>org.jvnet.jaxb2_commons</groupId>
        <artifactId>jaxb2-basics</artifactId>
        <version>0.9.1</version>
    </dependency>

我正在使用

maven-jaxb2-plugin

从xsd生成类的插件。

我试图反序列化json,可以通过两种方式接收:

{
    "config": {
         "field1": 1,
         "field2": 2,
         "object1": {
              .
              .
         }
    }
}

{
    "config": false
}

对于后者,我希望

{
    "config": {}
}

但事实并非如此,我对此也没有影响。

当我反序列化时,我得到一个异常

Caused by: com.fasterxml.jackson.databind.JsonMappingException: Can not deserialize instance of com.my.model.ConfigMap out of VALUE_FALSE token

很清楚为什么我会得到这个例外。

我一直在尝试使用自定义反序列化程序来解决这个问题,但不成功。

public class ConfigTypeDeserializer extends JsonDeserializer<ConfigType> {
    @Override
    public ConfigType deserialize(JsonParser jsonParser, DeserializationContext deserializationContext) throws IOException, JsonProcessingException {
        ObjectCodec cd = jsonParser.getCodec();
        JsonNode node = cd.readTree(jsonParser);

        ConfigType object = new ObjectFactory().createConfigType();
        if (node.isBoolean()) {
            return object;
        }

        // now I know its not a weird response so now I want to deserialize as usual

        return object;
    }

}

所以我检查是否看到了奇怪的响应,如果是,我返回一个空对象,如果不是,我想通过反序列化通常返回对象,因为该对象太复杂,无法在此反序列化器中手动完全构建它。但我没有办法做到这一点。我可以,例如致电

cd.readValue(jsonParser,ConfigType.class);

但这确实产生了一个ConfigType对象,但内容不正确。我没有得到预期的对象类型。

所以我想知道是否可以使用(或继续)自定义反序列化器中的现有反序列化代码。

如果那是不可能的,还有其他办法吗?

1 个答案:

答案 0 :(得分:0)

我发现了一个非常整洁的库

https://github.com/jonpeterson/jackson-module-json-interceptor

使用maven:

<dependency>
    <groupId>com.github.jonpeterson</groupId>
    <artifactId>jackson-module-json-interceptor</artifactId>
    <version>1.0.0</version>
</dependency>

使我能够在反序列化对象之前拦截反序列化过程。

您可以使用此注释

@JsonInterceptors(beforeDeserialization = {
    MyDeserializationInterceptor.class
})
public class MyProblematicObject {
..
}

在我的拦截器类中,我可以这样做

public class MyDeserializationInterceptor implements JsonInterceptor {
    @Override
    public JsonNode intercept(JsonNode node, JsonNodeFactory nodeFactory) {
        JsonNode config = node.findValue("config");

        // convert boolean to object
        if (node.isObject() && config.isBoolean()) {
            ObjectNode objectNode = nodeFactory.objectNode();
            ((ObjectNode)node).set("config",objectNode);
        }

        return node;
    }
}

反序列化过程愉快地继续:)

谢谢Jon Peterson !!