【问题标题】:jackson serialization of nested objects嵌套对象的杰克逊序列化
【发布时间】:2016-01-14 02:44:35
【问题描述】:

我在通过其接口对对象进行杰克逊序列化时遇到问题。

我有课

class Point implements PointView {

    private String id;

    private String name;

    public Point() {

    }

    public Point(String id, String name) {
        this.id = id;
        this.name = name;
    }

    @Override
    public String getId() {
        return id;
    }

    public String getName() {
        return name;
    }

}

实现了

interface PointView {
    String getId();
}

上课

class Map implements MapView {

    private String id;

    private String name;

    private Point point;

    public Map() {

    }

    public Map(String id, String name, Point point) {
        this.id = id;
        this.name = name;
        this.point = point;
    }

    @Override
    public String getId() {
        return id;
    }

    public String getName() {
        return name;
    }

    @JsonSerialize(as = PointView.class)
    public Point getPoint() {
        return point;
    }

}

实现了

interface MapView {
    String getId();
    Point getPoint();
}

还有上课

class Container {

    private Map map;

    public Container() {

    }

    public Container(Map map) {
        this.map = map;
    }

    @JsonSerialize(as = MapView.class)
    public Map getMap() {
        return map;
    }
}

我想用 Jackson 序列化 Container 并得到结果

{"map":{"id":"mapId","point":{"id":"pointId"}}}

但实际上我得到了结果

{"map":{"id":"mapId","point":{"id":"pointId","name":"pointName"}}}

尽管我在 Map (@JsonSerialize(as = PointView.class)) 中指定了 Point 的序列化类型,但在嵌套对象“point”中具有属性“name”。接口 PointView 没有方法 getName,但结果中存在 Point 的“名称”字段。

如果我从类 Container 中的方法 getMap 中删除注释 (@JsonSerialize(as = MapView.class)),我会得到结果

{"map":{"id":"mapId","name":"mapName","point":{"id":"pointId"}}}

现在点没有属性“名称”,但地图有。

我怎样才能得到结果

{"map":{"id":"mapId","point":{"id":"pointId"}}}

?

【问题讨论】:

  • 我找到了这个问题的解决方案。注解@JsonSerialize 也必须设置在接口interface MapView { String getId(); @JsonSerialize(as = PointView.class) Point getPoint(); }
  • 最佳:您将解决方案写成答案,打勾是正确的。 (尽快)

标签: java json serialization jackson


【解决方案1】:

要获得所需的结果,接口中的相同方法也必须用@JsonSerialize注释

interface MapView {
    String getId();
    @JsonSerialize(as = PointView.class)
    Point getPoint();
}

【讨论】:

    【解决方案2】:

    是的,你可以使用

    @JsonSerialize(as=MyInterface.class)
    public class ConcreteClass implements MyInterface { .... }
    

    在实现类(如上)或具有价值的属性上。

    【讨论】:

      【解决方案3】:

      你可以像这样注释方法:

      @JsonIgnore
      public String getName() {
          return name;
      }
      

      或者,如果您希望在此用例中进行特定序列化,而在其他用例中进行正常序列化,则可以使用@JsonView(请参阅doc)。

      它序列化 name 的原因是 instance 具有访问器 getName(),即使接口没有。

      【讨论】:

      • 是的。 @JsonIgnore 有效。但是类 Point 可能是其他类的一部分,其序列化必须包含 Point 的“名称”属性。我只想通过其接口指定类的序列化。有可能吗?
      • @JsonView 有问题。如果Point 类将有几个其他嵌套对象,并且每个嵌套对象都有它们的嵌套对象。对于@JsonView,我必须将此注释设置为所有嵌套对象,以将它们包含在序列化中。考虑到嵌套对象链可能非常大,这并不好。我希望每个类都可以设置序列化视图每个嵌套对象
      • 您可以为该对象创建一个deep copy,并将其 Point 对象的名称字段设为空。
      • 是的。深拷贝可能会有所帮助。但我不想为深拷贝编写额外的代码。我搜索这个问题的好解决方案
      • 波西米亚人,谢谢你的帮助。我找到了这个问题的解决方案。注解@JsonSerialize也必须在接口interface MapView { String getId(); @JsonSerialize(as = PointView.class) Point getPoint(); }中设置
      猜你喜欢
      • 2016-12-07
      • 2019-11-15
      • 2021-10-02
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-11-04
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多