我正在使用杰克逊作为工具来声明一些我无法注释(或完全修改)类的对象.其中一个类有一个用于无类型列表的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; }
}
Run Code Online (Sandbox Code Playgroud)
这是我试图反序列化的JSON:
{ "members" : [ { "name" : "Mark" } ] }
Run Code Online (Sandbox Code Playgroud)
我会使用的天真代码是这样的:
ObjectMapper mapper = new ObjectMapper();
Family family = mapper.readValue(json, Family.class);
Member member = (Member) family.getMembers().get(0);
System.out.println(member.getName());
Run Code Online (Sandbox Code Playgroud)
但当然这失败了,因为杰克逊不知道创建一个列表Members而不是它的后备,一个LinkedHashMaps 的列表.
什么是指导杰克逊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;
}}));
Run Code Online (Sandbox Code Playgroud)
它有效,但似乎真的很低级(和冗长!)我正在尝试做什么.我在这里错过了什么?
我应该注意,我正在使用Jackson 1.8.2,但如果有令人信服的理由可以更新.
混合注释是我所缺少的难题的关键部分.以下是解决此问题的更简洁方法:
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);
}
Run Code Online (Sandbox Code Playgroud)
您可以使用哪些混合注释来注释受您控制的代理.当该混合类应用于真实类时,杰克逊的行为就像那些注释注释了真实类的成员一样.
在我的例子中,我JsonDeserialize.contentAs()用来指定容器的内容类型.但我相信大多数注释应该可以使用这种方法.
| 归档时间: |
|
| 查看次数: |
4557 次 |
| 最近记录: |