问题描述
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<Rule>
扩展如下:
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()
只返回我 {
(第一个标记),因此反序列化失败。
我试图将所有内容都放在同一行(没有回车),但我遇到了同样的问题。 这看起来很明显很简单,但我在网上和杰克逊文档中都找不到任何例子。 有什么建议或参考可以分享吗?
解决方法
改变你的反序列化方法如下:
您在反序列化步骤中阅读了整个 JsonNode
,并根据您在节点中找到的键值构建您自己的 TreeMap
。 (您可能需要向 Rule 类添加构造函数)
@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);
}