汎用タイプのカスタムJsonDeserializer
を実装できます。この汎用タイプには、ContextualDeserializer
も実装されています。例えば
、我々は一般的な値が含まれている次のような単純なラッパー型があるとしますのインスタンスに
{
"name": "Alice",
"age": 37
}
:我々は次のようになりますJSONをデシリアライズしたい
public static class Wrapper<T> {
public T value;
}
をこのようなクラス:
public static class Person {
public Wrapper<String> name;
public Wrapper<Integer> age;
}
ContextualDeserializer
フィールドのジェネリック型パラメータに基づいて、Person
クラスの各フィールドに固有のデシリアライザを作成できます。これにより、名前を文字列としてデシリアライズし、年齢を整数としてデシリアライズすることができます。
完全デシリアライザは、次のようになります。これは、ジャクソンで最初に呼び出されるよう
public static class WrapperDeserializer extends JsonDeserializer<Wrapper<?>> implements ContextualDeserializer {
private JavaType valueType;
@Override
public JsonDeserializer<?> createContextual(DeserializationContext ctxt, BeanProperty property) throws JsonMappingException {
JavaType wrapperType = property.getType();
JavaType valueType = wrapperType.containedType(0);
WrapperDeserializer deserializer = new WrapperDeserializer();
deserializer.valueType = valueType;
return deserializer;
}
@Override
public Wrapper<?> deserialize(JsonParser parser, DeserializationContext ctxt) throws IOException {
Wrapper<?> wrapper = new Wrapper<>();
wrapper.value = ctxt.readValue(parser, valueType);
return wrapper;
}
}
それは、まずここcreateContextual
を見ることが最善です。 BeanProperty
(たとえばWrapper<String>
)のフィールドのタイプを読み取り、最初のジェネリックタイプのパラメータ(たとえばString
)を抽出します。新しいデシリアライザを作成し、内側の型をvalueType
として格納します。
新しく作成されたデシリアライザでdeserialize
が呼び出されると、その値をラッパータイプ全体ではなく内部型としてデシリアライズし、デシリアライズされた値を含む新しいWrapper
を返すことができます。
このカスタムデシリアライザを登録するために、我々はそれを含むモジュールを作成し、そのモジュールを登録する必要があります。
SimpleModule module = new SimpleModule()
.addDeserializer(Wrapper.class, new WrapperDeserializer());
ObjectMapper objectMapper = new ObjectMapper();
objectMapper.registerModule(module);
私たちはその後、上からの例JSONをデシリアライズしようとした場合、私たちが見ることができます期待どおりに動作する:
Person person = objectMapper.readValue(json, Person.class);
System.out.println(person.name.value); // prints Alice
System.out.println(person.age.value); // prints 37
デシリアライザはJackson documentationでどのように機能するか、コンテキストについてのいくつかの詳細があります。
あなたは*宣言していることを見つけるためにリフレクションを使用することができます'foo'のタイプは' Foo 'です。それはそれです。それがあなたの最後の手段であるかどうかを言うためにジャクソンについて私は知らない。 ['Field#getGenericType'](http://docs.oracle.com/javase/8/docs/api/java/lang/reflect/Field.html#getGenericType--) –
Radiodef