[英]How to define a generic list deserializer through annotations with Jackson?
Let's say I have an object which has list properties: 假设我有一个具有列表属性的对象:
public class Citizen {
name
List<Tickets> tickets
List<Fines> fines
}
I'd like to define a generic custom deserializer for lists through annotations: 我想通过注释为列表定义一个通用的自定义反序列化器:
public class Citizen {
...
@JsonDeserializer(MyListDeserializer<Tickets>) // <-- generic deserializer
public void setTickets(List<Tickets> tickets) {
this.tickets = tickets;
}
@JsonDeserializer(MyListDeserializer<Fines>) // <-- how can I do that?
public void setFines(List<Fines> fines) {
this.fines = fines;
}
}
I'm looking for a way to create a "generic" deserializer — one that would be able to deserialize both types of lists, similar to ContextualDeserializer for mapping JSON to different types of maps with Jackson . 我正在寻找一种方法来创建一个“通用”反序列化器 - 一个能够反序列化两种类型的列表,类似于ContextualDeserializer,用于将JSON映射到与Jackson不同类型的地图 。
The final purpose is to implement custom deserializing logic in MyListDeserializer
to deserialize empty strings ""
as empty lists, but I'd like to know about a general approach, not just for empty strings. 最后的目的是在
MyListDeserializer
实现自定义反序列化逻辑,以将空字符串""
反序列化为空列表,但我想了解一般方法,而不仅仅是空字符串。
You can specify the deserializer class with which to deserialize the elements of the list with the contentUsing
attribute of the @JsonDeserializer
annotation. 您可以使用
@JsonDeserializer
注释的contentUsing
属性指定用于反序列化列表元素的反序列化器类。
public class Citizen {
...
@JsonDeserializer(contentUsing=MyListDeserializer.class)
public void setTickets(List<Tickets> tickets) {
this.tickets = tickets;
}
}
Make your deserializer extend JsonDeserializer<BaseClass>
and have a attribute in the BaseClass that stores the actual type of the concrete class. 使您的反序列化程序扩展
JsonDeserializer<BaseClass>
并在BaseClass中有一个属性,用于存储具体类的实际类型。
abstract class BaseTickets {
String ticketType;
public String getTicketType()
}
public class MyListDeserializer extends JsonDeserializer<BaseTickets> {
@Override
public BaseTickets deserialize(JsonParser jsonParser, DeserializationContext arg1) throws IOException, JsonProcessingException {
ObjectCodec oc = jsonParser.getCodec();
JsonNode node = oc.readTree(jsonParser);
Iterator<JsonNode> elements = node.getElements();
for (; elements.hasNext();) {
String type = (String) elements.next().get("ticketType");
if (type.equals()){
//create concrete type here
}
}
}
Or if you want a single deserializer for all List types with no common base class, then use the using
attribute, have MyListDeserializer
extend JsonDeserialize<Object>
. 或者,如果您想要一个没有公共基类的所有List类型的单个反序列化器,那么使用
using
属性,让MyListDeserializer
扩展JsonDeserialize<Object>
。 For determining the type of list element you would have to write a custom serializer that adds the type information to the list which can then be used in the generic deserializer. 要确定列表元素的类型,您必须编写一个自定义序列化程序,将类型信息添加到列表中,然后可以在通用反序列化程序中使用。
public class Citizen {
...
@JsonDeserializer(using=MyListDeserializer.class)
@JsonSerializer(using=MyListSerializer.class)
public void setTickets(List<Tickets> tickets) {
this.tickets = tickets;
}
}
public class MyListSerializer extends JsonSerializer<Object> {
@Override
public void serialize(Object list, JsonGenerator jgen, SerializerProvider provider) throws IOException, JsonProcessingException {
@SuppressWarnings("rawtypes")
jgen.writeStartObject();
String type = getListType(list);
jgen.writeStringField("listType", type);
jgen.writeObjectField("list", list)
}
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.