jackson将额外的字段反序列化为地图

我希望将JSON对象中的任何未知字段反序列化为地图中的条目,该地图是pojo的成员。

例如json

{ "knownField" : 5, "unknownField1" : "926f7c2f-1ae2-426b-9f36-4ba042334b68", "unknownField2" : "ed51e59d-a551-4cdc-be69-7d337162b691" } 

和pojo

 class myObject{ int knownField; Map unknownFields; // getters/setters whatever } 

有没有办法用jackson配置? 如果没有,是否有一种有效的方法来编写StdDeserializer来执行此操作(假设unknownFields的值可能是更复杂但众所周知的一致类型)?

有一个function和注释完全符合这个目的。

我测试过它和你的例子中的UUID一样:

 class MyUUIDClass { public int knownField; Map unknownFields = new HashMap<>(); // Capture all other fields that Jackson do not match other members @JsonAnyGetter public Map otherFields() { return unknownFields; } @JsonAnySetter public void setOtherField(String name, UUID value) { unknownFields.put(name, value); } } 

它会像这样工作:

  MyUUIDClass deserialized = objectMapper.readValue("{" + "\"knownField\": 1," + "\"foo\": \"9cfc64e0-9fed-492e-a7a1-ed2350debd95\"" + "}", MyUUIDClass.class); 

更常见的类型如字符串工作:

 class MyClass { public int knownField; Map unknownFields = new HashMap<>(); // Capture all other fields that Jackson do not match other members @JsonAnyGetter public Map otherFields() { return unknownFields; } @JsonAnySetter public void setOtherField(String name, String value) { unknownFields.put(name, value); } } 

( 我在这篇博文中首先发现了这个function )。

你需要编写自定义反序列化器这样的东西

 class CustomDeserializer extends StdDeserializer{ public CustomDeserializer(Class t) { super(t); } @Override public MyObject deserialize(JsonParser parser, DeserializationContext context) throws IOException, JsonProcessingException { int knownField=0; Map unknownFields = new HashMap(); JsonToken currentToken = null; while ((currentToken = parser.nextValue()) != null) { switch (currentToken) { case VALUE_NUMBER_INT: if (parser.getCurrentName().equals("knownField")) { knownField = parser.getIntValue(); } break; case VALUE_STRING: if (parser.getCurrentName().startsWith("unknownField")){ unknownFields.put(parser.getCurrentName(),UUID.fromString(parser.getValueAsString())); } break; default: break; } } return new MyObject(knownField,unknownFields); } } 

然后按如下方式设置自定义反序列化器

 ObjectMapper mapper = new ObjectMapper(); SimpleModule mod = new SimpleModule("TestModule"); mod.addDeserializer(MyObject.class, new CustomDeserializer(MyObject.class)); mapper.registerModule(mod); MyObject myObj = mapper.readValue(contents, MyObject.class); 

编辑:您可以在按START_OBJECT标记时反序列化任何复杂对象。 并使用DeserializationContext.readValue(JsonParser, Class)反序列化MyObject