显然,它不起作用,因为Jackson使用标准集合解串器作为Java集合类型,它们对ItemList属性一无所知.
它可以使其工作,但不是非常优雅的方式.您需要配置ObjectMapper来替换为相应类型手动创建的bean解串器上的默认集合解串器.我已经写了一个例子,在BeanDeserializerModifier中为使用自定义注释注释的所有类执行此操作.
请注意,我必须重写ObjectMapper以访问ObjectMapper的受保护方法createDeserializationContext,以创建适当的反序列化上下文,因为bean修饰符无法访问它.
这是代码:
public class JacksonCustomList {
public static final String JSON = "{\n" +
" \"item\": [\n" +
" { \"foo\": 1 },\n" +
" { \"foo\": 2 }\n" +
" ]\n" +
"} ";
@Retention(RetentionPolicy.RUNTIME)
public static @interface PreferBeanDeserializer {
}
public static class Item {
public int foo;
@Override
public String toString() {
return String.valueOf(foo);
}
}
@PreferBeanDeserializer
public static class ItemList extends ArrayList {
@JsonProperty("item")
public List items;
@Override
public String toString() {
return items.toString();
}
}
public static class Modifier extends BeanDeserializerModifier {
private final MyObjectMapper mapper;
public Modifier(final MyObjectMapper mapper) {
this.mapper = mapper;
}
@Override
public JsonDeserializer> modifyCollectionDeserializer(
final DeserializationConfig config,final CollectionType type,final BeanDescription beanDesc,final JsonDeserializer> deserializer) {
if (type.getRawClass().getAnnotation(PreferBeanDeserializer.class) != null) {
DeserializationContext context = mapper.createContext(config);
try {
return context.getFactory().createBeanDeserializer(context,type,beanDesc);
} catch (JsonMappingException e) {
throw new IllegalStateException(e);
}
}
return super.modifyCollectionDeserializer(config,beanDesc,deserializer);
}
}
public static class MyObjectMapper extends ObjectMapper {
public DeserializationContext createContext(final DeserializationConfig cfg) {
return super.createDeserializationContext(getDeserializationContext().getParser(),cfg);
}
}
public static void main(String[] args) throws IOException {
final MyObjectMapper mapper = new MyObjectMapper();
SimpleModule module = new SimpleModule();
module.setDeserializerModifier(new Modifier(mapper));
mapper.registerModule(module);
System.out.println(mapper.readValue(JSON,ItemList.class));
}
}