Bạn có thể triển khai JsonDeserializer
tùy chỉnh cho loại chung của mình cũng thực hiện ContextualDeserializer
.
Ví dụ, giả sử chúng ta có các loại wrapper đơn giản sau đây có chứa một giá trị chung:
public static class Wrapper<T> {
public T value;
}
Bây giờ chúng ta muốn deserialize JSON trông như thế này:
{
"name": "Alice",
"age": 37
}
vào một thể hiện của một lớp trông như thế này:
public static class Person {
public Wrapper<String> name;
public Wrapper<Integer> age;
}
Triển khai ContextualDeserializer
cho phép chúng ta tạo ra một deserializer cụ thể cho từng trường trong lớp Person
, dựa trên các tham số kiểu chung của trường. Điều này cho phép chúng tôi deserialize tên như một chuỗi, và tuổi như một số nguyên.
Các deserializer hoàn toàn trông như thế này:
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;
}
}
Tốt nhất là nhìn vào createContextual
đây đầu tiên, vì điều này sẽ được gọi đầu tiên của Jackson. Chúng tôi đọc loại trường từ số BeanProperty
(ví dụ: Wrapper<String>
) và sau đó trích xuất thông số loại chung chung đầu tiên (ví dụ: String
). Sau đó, chúng tôi tạo trình khử giải phóng mới và lưu trữ loại bên trong là valueType
.
Sau khi deserialize
được gọi trên deserializer mới được tạo ra này, chúng tôi chỉ đơn giản có thể yêu cầu Jackson deserialize giá trị như loại bên trong chứ không phải là toàn bộ loại wrapper, và trả lại một mới Wrapper
chứa giá trị deserialized.
Để đăng ký deserializer tùy chỉnh này, sau đó chúng tôi cần phải tạo ra một mô-đun chứa nó, và đăng ký rằng mô-đun:
SimpleModule module = new SimpleModule()
.addDeserializer(Wrapper.class, new WrapperDeserializer());
ObjectMapper objectMapper = new ObjectMapper();
objectMapper.registerModule(module);
Nếu sau đó chúng tôi cố gắng deserialize ví dụ JSON từ trên cao, chúng ta có thể thấy hoạt động như mong đợi:
Person person = objectMapper.readValue(json, Person.class);
System.out.println(person.name.value); // prints Alice
System.out.println(person.age.value); // prints 37
Có một số chi tiết khác về cách hoạt động của công cụ giải mã theo ngữ cảnh trong Jackson documentation.
Bạn có thể sử dụng phản ánh để tìm ra rằng * tuyên bố * loại 'foo' là' Foo '. Đó là về nó. Tôi không biết về Jackson để nói nếu đó là một phương tiện để kết thúc của bạn ở đây. ['Field # getGenericType'] (http://docs.oracle.com/javase/8/docs/api/java/lang/reflect/Field.html#getGenericType--) –
Radiodef