gpt4 book ai didi

java - 如何为 Jackson 反序列化器提供类型提示?

转载 作者:塔克拉玛干 更新时间:2023-11-03 03:45:34 24 4
gpt4 key购买 nike

我正在使用 Jackson 作为一种工具来声明一些我无法注释(或根本无法修改)其类的对象。其中一个类有一个用于无类型列表的 setter 和 getter。这是经过清理的版本:

public class Family {
private List members;
public List getMembers() { return members; }
public void setMembers(List members) { this.members = members; }
//...many, many other properties
}

public class Member {
private String name;
public String getName() { return name; }
public void setName(String name) { this.name = name; }
}

这是我要反序列化的 JSON:

{ "members" : [ { "name" : "Mark" } ] }

我会使用的天真的代码是这样的:

ObjectMapper mapper = new ObjectMapper();
Family family = mapper.readValue(json, Family.class);
Member member = (Member) family.getMembers().get(0);
System.out.println(member.getName());

但这当然失败了,因为 Jackson 不知道创建 Members 的列表而不是它的后备,列表 LinkedHashMap

指导 jackson 治疗的最简单方法是什么members作为List<Member> ? 我不认为我想为该类使用完全自定义的反序列化器,因为 Jackson 可以很好地处理许多其他属性。

这是我能想到的最好的方法,使用 BeanDeserializerModifier:

mapper.setDeserializerProvider(new StdDeserializerProvider()
.withDeserializerModifier(new BeanDeserializerModifier() {
@Override
public BeanDeserializerBuilder updateBuilder(DeserializationConfig config, BasicBeanDescription beanDesc, BeanDeserializerBuilder builder) {
if (beanDesc.getBeanClass() == Family.class) {
CollectionType type = CollectionType.construct(ArrayList.class, SimpleType.construct(Member.class));
TypeDeserializer typeDeserializer = type.getTypeHandler();
SettableBeanProperty.MethodProperty membersProperty = (SettableBeanProperty.MethodProperty) builder.removeProperty("members");
builder.addProperty(new SettableBeanProperty.MethodProperty(
"members",
type,
typeDeserializer,
beanDesc.getClassAnnotations(),
(AnnotatedMethod) membersProperty.getMember()
));
}
return builder;
}}));

它有效,但对于我正在尝试做的事情来说似乎真的很低级(而且冗长!)。我在这里缺少什么?

编辑

我应该注意,我使用的是 Jackson 1.8.2,但如果有令人信服的理由可以更新。

最佳答案

Mix-in annotations是我所缺少的拼图的关键部分。这是解决此问题的更简洁的方法:

ObjectMapper mapper = new ObjectMapper();
mapper.getDeserializationConfig().addMixInAnnotations(Family.class, FamilyMixin.class);

Family family = mapper.readValue(json, Family.class);
Member member = (Member) family.getMembers().get(0);

//...

interface FamilyMixin {
@JsonDeserialize(contentAs = Member.class)
void setMembers(List members);
}

混合注解让你做的是注解一个在你控制下的代理。当该混合类应用于真实类时,Jackson 的行为就好像这些注释注释了真实类的成员一样。

在我的例子中,我使用 JsonDeserialize.contentAs() 来指定容器的内容类型。但我相信大多数注释应该可以使用这种方法。

关于java - 如何为 Jackson 反序列化器提供类型提示?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10835668/

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