【问题标题】:Jackson deserializer to handle two types as one杰克逊解串器将两种类型作为一种处理
【发布时间】:2016-05-16 14:17:03
【问题描述】:

我的服务器返回具有 2 种不同类型的结果:成功时的 SearchResultDTO 和错误时的字符串。我需要处理这两种类型并始终返回 SearchResultDTO 类型。这是我的反序列化器:

public class SearchResultsDeserializer extends JsonDeserializer<SearchResultDTO> {

    @Override
    public SearchResultDTO deserialize(JsonParser jp, DeserializationContext ctxt) throws IOException {
        JsonToken t = jp.getCurrentToken();
        if (t == JsonToken.VALUE_STRING){
            return new SearchResultDTO(jp.getText());
        } else {
            return jp.readValueAs(SearchResultDTO.class);
        }
    }
}

当我运行此代码并且服务器发送 SearchResultDTO 对象时,jackson 通过调用此函数进入无限循环并返回错误:“java.lang.StackOverflowError: stack size 1036KB”

【问题讨论】:

    标签: java android json jackson deserialization


    【解决方案1】:

    简单的解决方法是在 SearchResultsDeserializer 中创建 ObjectMapper 的新实例并使用它而不是 JsonParser

    public static class SearchResultsDeserializer extends JsonDeserializer<SearchResultDTO> {
        private static ObjectMapper mapper = new ObjectMapper();
        @Override
        public SearchResultDTO deserialize(JsonParser jp, DeserializationContext ctxt) throws IOException {
            JsonToken t = jp.getCurrentToken();
            if (t == JsonToken.VALUE_STRING){
                return new SearchResultDTO(jp.getText());
            } else {
                return mapper.readValue(jp, SearchResultDTO.class);
            }
        }
    }
    

    困难的方法是将默认反序列化器保存在您的自定义反序列化器中。 这里有更多信息:How do I call the default deserializer from a custom deserializer in Jackson

    【讨论】:

    • @JohnnyDepp 如果您 100% 确定您拥有完全不同的映射器,而没有在他身上注册 SearchResultsDeserializer,您可能需要向我们展示您的其余代码。因为这 100% 对我有用,所以这里是演示 gist.github.com/varren/38b76c4a62fc5024caedcdc469606649 我想你用注释注册了你的反序列化器,这样我认为没有什么可以帮助你。如果你使用注解,你将不得不为jp.readValueAs(SearchResultDTO.class);编写自定义实现
    • @JohnnyDepp 但是为什么你首先需要一个反序列化器。您只需在构造函数中使用字符串 arg 给出错误刺痛。杰克逊可以理解这一点。如果您在 json 中给出字符串而不是对象,则默认行为是使用 String args 构造函数。
    • 关于默认构造函数的要点。大概我会选择这种方式。但我想为将来的使用做一些通用的解决方案。是的,我用注释注册了反序列化器。
    猜你喜欢
    • 2012-09-13
    • 2021-09-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-05-25
    • 2023-03-27
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多