杰克逊 - 将 POJO 包装在带有元数据的包装类中 - 陷入无限循环



>我有一个模型类,我想包装它以输出 REST 服务。

public class Model {
    private String name;
    // getter..setter;
}
public class Wrapper {
    private Model model;
    private Date modifiedDate;
    // getter..setter;
}
public class Converter extends StdConverter<Model, Wrapper> {
    @Override
    public Wrapper convert(Model model) {
        return new Wrapper(model, new Date());
    }
}

输出是沿线的 json

{
  "model": {
     "name" : "dave"
  },
  "date": "tuesday"
}

问题是它似乎陷入了循环。不断尝试序列化模型,

嵌套在其中。

我试过添加@JsonSerialize(converter = Converter.class)并在我的对象映射器中设置module.addSerializer(Model.class, new StdDelegatingSerializer(new Converter()));,但每次都得到相同的结果。

使用杰克逊 2.8.5

您可以创建Model的代理并使用该代理来创建Wrapper。这样您就可以防止循环。

public class Converter extends StdConverter<Model, Wrapper> {
    @Override
    public Wrapper convert(Model model) {
        return new Wrapper(new ModelProxy(model), new Date());
    }
}

模型代理的实现:

public class ModelProxy {
    private final Model model;
    public ModelProxy(final Model model) {
        this.model = model;
    }
    public String getName() {
        return model.getName();
    }
}
我想

用一种减少所需代码量的方法修改@nielle85的答案。

方法是让ModelProxy扩展Model并使用注释禁用其转换,而不是使用聚合类。这样,所需要的只是一个复制构造函数。

示例代码:

@JsonSerialize(converter = ModelConverter.class)
public class Model {
   // Getters, setters and fields omitted.
}
@JsonSerialize(converter = Converter.None.class)
public class ModelProxy extends Model {
    public ModelProxy(Model model) {
        // Copy constructor
    }
}

复制构造函数可以简单地实现,并使用 Bean-mapping框架(如 Apache Beanutils 或 Dozer)保持最新状态。

最新更新