私はJSONオブジェクトの不明なフィールドを、pojoのメンバーであるマップのエントリーとしてデシリアライズしようとしています。
たとえば、json
{
"knownField" : 5,
"unknownField1" : "926f7c2f-1ae2-426b-9f36-4ba042334b68",
"unknownField2" : "ed51e59d-a551-4cdc-be69-7d337162b691"
}
とポージョ
class myObject{
int knownField;
Map<String, UUID> unknownFields;
// getters/setters whatever
}
ジャクソンでこれを構成する方法はありますか?そうでない場合、それを行うためにStdDeserializer
を書き込む効果的な方法はありますか(unknownFields
の値はより複雑ですがよく知られている一貫した型であると想定してください)?
この目的にぴったり合う機能と注釈があります。
私はテストし、あなたの例のようにUUIDで動作します:
class MyUUIDClass {
public int knownField;
Map<String, UUID> unknownFields = new HashMap<>();
// Capture all other fields that Jackson do not match other members
@JsonAnyGetter
public Map<String, UUID> 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<String, String> unknownFields = new HashMap<>();
// Capture all other fields that Jackson do not match other members
@JsonAnyGetter
public Map<String, String> otherFields() {
return unknownFields;
}
@JsonAnySetter
public void setOtherField(String name, String value) {
unknownFields.put(name, value);
}
}
あなたはこのような何かをカスタムデシリアライザを書く必要があります
_class CustomDeserializer extends StdDeserializer<MyObject>{
public CustomDeserializer(Class<MyObject> t) {
super(t);
}
@Override
public MyObject deserialize(JsonParser parser, DeserializationContext context)
throws IOException, JsonProcessingException {
int knownField=0;
Map<String, UUID> unknownFields = new HashMap<String, UUID>();
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>)
を使用してMyObjectをデシリアライズします