【问题标题】:Deserializing data which can be object or boolean反序列化可以是对象或布尔值的数据
【发布时间】:2017-07-23 15:26:33
【问题描述】:

我正在使用具有以下依赖项的 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 对象,但内容不正确。我没有得到预期的对象类型。

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

如果这不可能,还有其他方法吗?

【问题讨论】:

    标签: jaxb jackson


    【解决方案1】:

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

    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;
        }
    }
    

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

    谢谢乔恩·彼得森!!

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2019-12-09
      • 1970-01-01
      • 2015-07-03
      • 1970-01-01
      • 1970-01-01
      • 2012-09-09
      • 2016-09-11
      相关资源
      最近更新 更多