如何通过jackson的注释定义通用列表反序列化器?

假设我有一个具有列表属性的对象:

public class Citizen { name List tickets List fines } 

我想通过注释为列表定义一个通用的自定义反序列化器:

 public class Citizen { ... @JsonDeserializer(MyListDeserializer) // <-- generic deserializer public void setTickets(List tickets) { this.tickets = tickets; } @JsonDeserializer(MyListDeserializer) // <-- how can I do that? public void setFines(List fines) { this.fines = fines; } } 

我正在寻找一种方法来创建一个“通用”反序列化器 – 一个能够反序列化两种类型的列表,类似于ContextualDeserializer,用于将JSON映射到与Jackson不同类型的地图 。

最后的目的是在MyListDeserializer实现自定义反序列化逻辑,以将空字符串""反序列化为空列表,但我想了解一般方法,而不仅仅是空字符串。

您可以使用@JsonDeserializer注释的contentUsing属性指定反序列化器类,使用该类反序列化列表元素。

 public class Citizen { ... @JsonDeserializer(contentUsing=MyListDeserializer.class) public void setTickets(List tickets) { this.tickets = tickets; } } 

使您的反序列化器扩展JsonDeserializer并在BaseClass中有一个属性,用于存储具体类的实际类型。

 abstract class BaseTickets { String ticketType; public String getTicketType() } public class MyListDeserializer extends JsonDeserializer { @Override public BaseTickets deserialize(JsonParser jsonParser, DeserializationContext arg1) throws IOException, JsonProcessingException { ObjectCodec oc = jsonParser.getCodec(); JsonNode node = oc.readTree(jsonParser); Iterator elements = node.getElements(); for (; elements.hasNext();) { String type = (String) elements.next().get("ticketType"); if (type.equals()){ //create concrete type here } } } 

或者,如果要为没有公共基类的所有List类型使用单个反序列化器,则使用using属性,让MyListDeserializer扩展JsonDeserialize 。 要确定列表元素的类型,您必须编写一个自定义序列化程序,将类型信息添加到列表中,然后可以在通用反序列化程序中使用。

 public class Citizen { ... @JsonDeserializer(using=MyListDeserializer.class) @JsonSerializer(using=MyListSerializer.class) public void setTickets(List tickets) { this.tickets = tickets; } } public class MyListSerializer extends JsonSerializer { @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) } }