gpt4 book ai didi

java - 使用 Jackson 实现 Collection 的类的反序列化失败

转载 作者:塔克拉玛干 更新时间:2023-11-03 02:59:16 30 4
gpt4 key购买 nike

我有以下 JSON:

{
"item": [
{ "foo": 1 },
{ "foo": 2 }
]
}

这基本上是一个包含项目集合的对象。

所以我做了一个类来反序列化:

public class ItemList {
@JsonProperty("item")
List<Item> items;

// Getters, setters & co.
// ...
}

到目前为止一切正常。

现在,为了让我在其他地方的生活更轻松,我决定能够迭代 ItemList 对象并让它实现 Collection 接口(interface)会很好。

所以基本上我的类(class)变成了:

public class ItemList implements Collection<Item>, Iterable<Item> {
@JsonProperty("item")
List<Item> items;

// Getters, setters & co.

// Generated all method delegates to items. For instance:
public Item get(int position) {
return items.get(position);
}
}

实现工作正常且很好。但是,反序列化现在失败了。

看起来 Jackson 越来越糊涂了:

com.fasterxml.jackson.databind.JsonMappingException: Can not deserialize instance of com.example.ItemList out of START_OBJECT token

我尝试添加 @JsonDeserialize(as=ItemList.class) 但它没有成功。

要走的路是什么?

最佳答案

显然它不起作用,因为 Jackson 对 Java 集合类型使用标准集合反序列化器,它对 ItemList 属性一无所知。

可以让它工作,但不是以一种非常优雅的方式。您需要配置 ObjectMapper 以替换为相应类型手动创建的 bean 反序列化器上的默认集合反序列化器。我已经在 BeanDeserializerModifier 中为所有使用自定义注释注释的类编写了一个示例。

请注意,我必须覆盖 ObjectMapper 才能访问 ObjectMapper 的 protected 方法 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<Item> {
@JsonProperty("item")
public List<Item> 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, type, 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));
}

}

关于java - 使用 Jackson 实现 Collection 的类的反序列化失败,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24894342/

30 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com