Jackson 将对象反序列化为相同的对象。

huangapple go评论75阅读模式
英文:

Jackson deserialize objects as the same one

问题

以下是您要翻译的内容:

我使用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("已经有了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); // 没有通过此断言
}
英文:

I was working with jackson's JsonIdentityInfo annatation, the serialization looks good. But the deserialization didnt work as I expected, the objects sharing the same id, are not deserialized into the same objects. Below are the class definitions.

class ParameterResolver implements ObjectIdResolver {
private final Map&lt;ObjectIdGenerator.IdKey,Object&gt; items = new HashMap&lt;&gt;();
@Override
public void bindItem(ObjectIdGenerator.IdKey id, Object pojo) {
if (items.containsKey(id)) {
throw new IllegalStateException(&quot;Already had POJO for id (&quot; + id.key.getClass().getName() + &quot;) [&quot; + id
+ &quot;]&quot;);
}
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(&quot;setId&quot;, 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 = &quot;id&quot;, 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;
}
}

and this is the unit test

    @Test
public void test() throws JsonProcessingException {
Parameter p1 = new Parameter(), p2 = new Parameter();
p1.setId(1);
p1.setData(&quot;1&quot;);
List&lt;Container&gt; list = new ArrayList&lt;&gt;();
list.add(new Container(p1));
list.add(new Container(p1));
ObjectMapper mapper = new ObjectMapper();
String content = mapper.writerWithDefaultPrettyPrinter().writeValueAsString(list);
List&lt;Container&gt; listD = mapper.readValue(content, new TypeReference&lt;List&lt;Container&gt;&gt;() {});
assertSame(listD.get(0).p, list.get(1).p); // didnt pass this assertion
}

答案1

得分: 2

反序列化从JSON创建新对象。共享相同id的对象被反序列化为相同的对象。然而,这些对象与先前序列化的对象不同。

在您的断言中,您正在比较一个反序列化的参数实例与用于序列化的实例:

assertSame(listD.get(0).p, list.get(1).p); // 这个断言未通过

您应该比较两个反序列化的实例:

assertSame(listD.get(0).p, listD.get(1).p);

请注意第二个参数listD.get(1).p中的' D '。

英文:

Deserialization creates new objects from JSON. Objects sharing the same id are deserialized into the same objects. However, these are different objects than those that were previously serialized.

In your assertion you are comparing a deserialized parameter instance with an instance that was used for serialization:

assertSame(listD.get(0).p, list.get(1).p); // didnt pass this assertion

You should compare the two deserialized instances instead:

assertSame(listD.get(0).p, listD.get(1).p); 

Please note the 'D' in the second parameter listD.get(1).p.

huangapple
  • 本文由 发表于 2020年8月13日 16:47:14
  • 转载请务必保留本文链接:https://go.coder-hub.com/63391421.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定