繁体   English   中英

Jackson 反序列化对象为同一个

[英]Jackson deserialize objects as the same one

我正在使用杰克逊的JsonIdentityInfo注释,序列化看起来不错。 但是反序列化没有像我预期的那样工作,共享相同 id 的对象没有反序列化为相同的对象。 以下是 class 定义。

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”。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM