Jackson @JsonIgnore 继承的 Java 8 默认方法

Abd*_*ull 2 json jackson java-8 default-method

我有一个带有默认方法的接口:

public interface Book {

    String getTitle();

    default String getSentenceForTitle() {
        return "This book's title is " + getTitle();
    }

}
Run Code Online (Sandbox Code Playgroud)

...我有一个@Entity实现这个接口的JPA :

@Entity
public class JpaBook implements Book {

    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    private Long id;

    private String title;

    // ...

    @Override
    public String getTitle() {
        return title;
    }

}
Run Code Online (Sandbox Code Playgroud)

使用这个实体,我注意到 Jackson 也会序列化默认方法getSentenceForTitle()- 尽管在我的特殊情况下,我不想sentenceForTitle被序列化。

有没有办法让杰克逊知道我不想序列化默认方法,但要保留该方法的行为?我想出的当前解决方法是覆盖默认方法,用 注释它@JsonIgnore,然后委托给默认方法:

@Entity
public class JpaBook implements Book {

    // ...

    @Override
    @JsonIgnore
    public String getSentenceForTitle() {
        return Book.super.getSentenceForTitle();
    }

}
Run Code Online (Sandbox Code Playgroud)

但是对于具有许多默认方法的接口,此解决方案可能会变得非常冗长且容易出错。

Man*_*dis 5

为了忽略特定的方法/字段,必须以某种方式指定,注释是最简单的方法。我可以推荐以下比您尝试过的更简单的选项:

  1. 注释默认方法而不在JpaBook. 所以在Book

    @JsonIgnore
    default String getSentenceForTitle() {
        return "This book's title is " + getTitle();
    }
    
    Run Code Online (Sandbox Code Playgroud)
  2. 如果Book不在您的控制之下,或者您想要方便地指定一个字段列表,您可以保持Book原样并使用JpaBook要忽略的字段或字段数组进行注释。例如:

    @JsonIgnoreProperties("sentenceForTitle")
    class JpaBook implements Book {
    
    Run Code Online (Sandbox Code Playgroud)

    或者

    @JsonIgnoreProperties({"sentenceForTitle", "alsoIgnoreThisField"})
    class JpaBook implements Book {
    
    Run Code Online (Sandbox Code Playgroud)
  3. 您还可以注释JpaBook以序列化所有字段 (of JpaBook) 并忽略所有 getter。你不需要做任何事情,Book例如:

    @JsonAutoDetect(fieldVisibility = ANY, getterVisibility = NONE)
    class JpaBook implements Book {
    
    Run Code Online (Sandbox Code Playgroud)