如何通过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