如何解决杰克逊将对象反序列化为同一对象
我正在和杰克逊(Jackson)的JsonIdentityInfo
约会一起工作,序列化看起来不错。但是反序列化没有按我预期的那样工作,共享相同ID的对象没有反序列化为相同的对象。下面是类的定义。
class ParameterResolver implements ObjectIdResolver {
private final Map<ObjectIdGenerator.IdKey,Object> items = new HashMap<>();
@Override
public void bindItem(ObjectIdGenerator.IdKey id,Object pojo) {
if (items.containsKey(id)) {
throw new IllegalStateException("Already had POJO for id (" + id.key.getClass().getName() + ") [" + id
+ "]");
}
items.put(id,pojo);
}
@Override
public Object resolveId(ObjectIdGenerator.IdKey id) {
Object object = items.get(id);
return object == null ? getById(id) : object;
}
protected Object getById(ObjectIdGenerator.IdKey id){
Object object;
try {
object = id.scope.getConstructor().newInstance();
id.scope.getMethod("setId",Integer.class).invoke(object,(Integer) id.key);
} catch (Exception e) {
throw new IllegalStateException(e);
}
items.put(id,object);
return object;
}
@Override
public ObjectIdResolver newForDeserialization(Object context) {
return new ParameterResolver();
}
@Override
public boolean canUseFor(ObjectIdResolver resolverType) {
return resolverType.getClass() == getClass();
}
}
@JsonIdentityInfo(generator = ObjectIdGenerators.PropertyGenerator.class,resolver = ParameterResolver.class,property = "id",scope = Parameter.class)
class Parameter {
private Integer id;
private String data;
public Parameter() {}
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getData() {
return data;
}
public void setData(String data) {
this.data = data;
}
}
class Container {
public Parameter p;
public Container() {}
public Container(Parameter p) {
this.p = p;
}
}
这是单元测试
@Test
public void test() throws JsonProcessingException {
Parameter p1 = new Parameter(),p2 = new Parameter();
p1.setId(1);
p1.setData("1");
List<Container> list = new ArrayList<>();
list.add(new Container(p1));
list.add(new Container(p1));
ObjectMapper mapper = new ObjectMapper();
String content = mapper.writerWithDefaultPrettyPrinter().writeValueAsString(list);
List<Container> listD = mapper.readValue(content,new TypeReference<List<Container>>() {});
assertSame(listD.get(0).p,list.get(1).p); // didnt pass this assertion
}
解决方法
反序列化从JSON创建新对象。共享相同ID的对象反序列化为相同对象。但是,这些对象与先前序列化的对象不同。
在断言中,您正在将反序列化的参数实例与用于序列化的实例进行比较:
assertSame(listD.get(0).p,list.get(1).p); // didnt pass this assertion
您应该比较两个反序列化的实例:
assertSame(listD.get(0).p,listD.get(1).p);
请注意第二个参数listD.get(1).p
中的'D'。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。