java - 防止 Jackson @JsonIgnore 引入重复

标签 java json design-patterns jackson

我正在开发一个以这种方式架构的应用程序。
BaseObject 包含以下字段:

public class BaseObject {
    private String id;  
    private Instant creationDate;  
    private String createdBy;  
    private Instant lastEditionDate;  
    private String lastEditBy;  
    private Instant deletionDate;  
    private String deletedBy;
}

每个类都扩展这个 BaseObject,所以我最终得到两个像这样的 POJO:

public class Pojo1 extends BaseObject {
    private SubPojo1 subPojo1;
    private SubPojo2 subPojo2;
}

public class Pojo2 extends BaseObject {
    private SubPojo3 subPojo3;
    private SubPojo4 subPojo4;
}

这两个 POJOS 没有功能关系。它们由 SubPojo 组成,SubPojo 以功能性方式对字段进行分组。

我的问题来了。我的应用程序通过 JSON 将数据发送到 BI 应用程序。 BI 应用程序需要将 POJO 转换为“平面”格式,并且我想排除 BaseObject 字段。

所以我想出了这个:

public class FlatPojo1 extends Pojo1 {
    @Override
    @JsonIgnore
    public String getId() {
        return super.getId();
    }
    /* Override every getter of BaseObjet */

    @Override
    @JsonUnwrapped
    public SubPojo1 getSubPojo1 {
        return super.getSubPojo1();
    }
    /* Override every getter of Pojo1 */
}

我的解决方案正在运行,BI 应用程序获取正确格式的数据,我仍然可以使用子对象处理我的对象。

令我困扰的是代码重复。对于每个平面对象,我必须重写 BaseObject 的每个 getter。我不想这样做。

Java 不允许多重继承,因此我无法创建一个抽象类来 @JsonIgnore 每个 BaseObject 字段并扩展我的 Pojo1。

我尝试提供这样的界面:

public interface BaseObjectInterface {
    String getId();
    Instant getCreationDate();
    // etc
}

我的BaseObject现在实现了BaseObjectInterface,一切都很好。然后计划是创建一个FlatData接口(interface),它将@JsonIgnore BaseObject字段,并且每个FlatPojo都将实现这个接口(interface)。我想出了这个:

public interface FlatData extends BaseObjectInterface {
    @Override
    @JsonIgnore
    default String getId() {
        BaseObjectInterface.super.getId(); // Error
    }

我收到一条错误消息,告诉我无法调用抽象方法。而且我无法在 BaseObjectInterface 中创建默认的 getId() 方法,因为这需要一个 id 字段,并且接口(interface)中的每个字段都是静态的。

我找不到避免重复所有这些@JsonIgnore 的方法。有什么办法可以做到吗?
感谢您的帮助。

最佳答案

您可以使用Mixin注释,在界面中添加注释:

 public interface BaseObjectMixIn {
        @JsonIgnore
        String getId();

        ... rest of annotations for superclass
    }

这样你就不必添加任何东西,只需将 mixin 添加到映射器即可:

ObjectMapper mapper = new ObjectMapper();
mapper.addMixInAnnotations(Pojo1.class, BaseObjectMixIn.class);

String json = mapper.writer().writeValueAsString(pojo1);

如果您希望每个 BaseObject 子类都有它:

ObjectMapper mapper = new ObjectMapper();
mapper.addMixInAnnotations(BaseObject.class, BaseObjectMixIn.class);

但是一个更简单的解决方案,没有mixin,并且只向子类添加一个接口(interface)是:

  public interface BaseOjectInterface {
        @JsonIgnore
        String getId();
    }

 public static class Pojo1 extends BaseObject implements BaseOjectInterface  {
        private String subPojo1;
        private String subPojo2;

这将避免在序列化 Pojo1 时从 BaseObject 发送 id

关于java - 防止 Jackson @JsonIgnore 引入重复,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38646854/

相关文章:

qt - 鼠标交互的设计模式

java - 决定运行时的方法使用。多态性

java - 对于我的应用程序的 SSL 使用,我如何影响 'known_hosts' 与 self 认证的服务器?

java - 如何避免在 Java 泛型扩展 Comparable 接口(interface)中进行未经检查的强制转换?

javascript - 将表提取为 JSON 对象

java - 页面日志记录的设计模式

java - 抽象类中实现的单元测试方法,没有具体实现

java - 如何将 admob 广告添加到应用程序中?

jQuery.ajax 响应数据未定义

java - 解决递归关系中的 StackOverflow 异常