当前位置: 首页 > 知识库问答 >
问题:

TreeMap的自定义反序列化程序-无法通过JsonParser获取全文

姬雪松
2023-03-14

我有一个定义如下的类:

class Rule {
    private final TreeMap<String, String> rule;
    public Rule(TreeMap<String, String> rule) {
        this.rule = rule;
    }
}

另一个类包含此类对象的列表:

class BigClass {
    
    @JsonProperty("rules")
    @JsonDeserialize(contentUsing = Rule.Deserializer.class)
    private final List<Rule> rules;

    //...

}

...并且正如@JSONDeserialize注释中所指定的,我希望自定义反序列化器处理此类列表的内容。

为此,我对JSONDeserializer 进行了如下扩展:

public static final class Deserializer extends JsonDeserializer<Rule> {

    private final ObjectMapper objectMapper = new ObjectMapper();

    @Override
    public Rule deserialize(JsonParser p, DeserializationContext ctxt) throws IOException {
        String strRule = p.getText();
        TypeReference<TreeMap<String, String>> typeReference = new TypeReference<>() {
        };

        TreeMap<String, String> ruleMap = objectMapper.readValue(strRule, typeReference);
        return new Rule(ruleMap);
    }
}

当我尝试用以下结构解析bigclass类型的Json时:

{
    ...
    "rules": [
        {
            "A": "B",
            "C": "D",
            "E": "F" 
        }
    ]
}

...在我自己的deserialize()方法中正确调用了我,但问题是表达式p.gettext()只返回我{(第一个令牌),因此反序列化失败。

我已经尝试把所有的东西都放在同一行(没有回车),但我也有同样的问题。这似乎是一个明显和简单的东西,但我找不到任何例子在网上或在jackson的文档。有什么建议或参考可以分享吗?

共有1个答案

王景山
2023-03-14

更改反序列化方法如下:在反序列化步骤中读取整个JSONNODe,并根据在节点中找到的键值构造自己的TreeMap。(您可能必须向规则类添加构造函数)

@Override
  public Rule deserialize(JsonParser p, DeserializationContext ctxt) throws IOException {
    JsonNode node = p.getCodec().readTree(p);
    TreeMap<String, String> ruleMap = new TreeMap<>();
    node.fields().forEachRemaining(e -> ruleMap.put(e.getKey(), e.getValue().textValue()));

    return new Rule(ruleMap);
  }
 类似资料:
  • 我正在尝试实现一个Jackson反序列化器,以便在JSON发生变化时能够迁移JSON(例如,在重命名的字段中,我需要将现在不一致的JSON读入一致的JSON)。 一种方法是创建JsonDeserializer,将JSON作为适当的最终类读取,然后将其作为映射再次读取,以挑选更改。 但我似乎无法做到这一点,因为每次我读取或反序列化JSON时,支持流都会关闭。 我避免创建新的ObjectMapper,

  • 情况如下:我已经设法让Jackson反序列化以下通用 作为HTTP客户端,并使用exchange

  • 我正在尝试为泛型列表创建一个自定义反序列化器。假设我得到了类B的json表示: 其中A是我仅在运行时看到的其他类。我想创建一个反序列化程序,该程序能够将listObject的类型推断为具有内部类型a的list,并将其反序列化,而不是使用默认的hashmap反序列化程序。 我尝试使用上下文反序列化器,类似于这里建议的,然后将其添加为List的自定义反序列化器 但是我不确定我应该如何读取json并在反

  • I'va是一个OID接口,可以由许多具体类型实现: 现在我有一个具有两个字段的对象,一个使用抽象接口类型(OID)定义,另一个使用具体类型(MyOID)定义 我想使用jackson以不同的方式序列化/反序列化字段,无论它们是使用抽象接口类型还是具体类型定义的: 注意,被序列化,包括类型信息(多态序列化),而被序列化为文本 为此,我将OID接口注释为: 并为每个具体类型分配了类型id: 最后,对容器

  • 我创建了一个新的自定义反序列化程序,当json中存在空字符串时,该反序列化程序将作为null返回 我的问题是从性能的角度来看的。我想优化一个事实,即在字段的每一个可能的更改中都必须更改反序列化器。有可能优化你的吗?我正在考虑使用Reflaction,但我不知道怎么做。有可能吗?

  • 我在Jackson的自定义反序列化程序中有一个问题。我想访问默认序列化程序来填充我要反序列化到的对象。在填充之后,我将执行一些自定义操作,但首先我要使用默认的Jackson行为反序列化对象。 这是我现在有的代码。 我需要的是一种初始化默认反序列化器的方法,这样我就可以在开始我的特殊逻辑之前预填充我的POJO。 当从自定义反序列化程序内调用deserialize时,无论我如何构造序列化程序类,该方法