在 Elasticsearch 中忽略 JsonIgnore

Arn*_*lle 3 java jackson elasticsearch spring-boot

我正在开发一个使用 Spring-boot、关系数据库和 Elasticsearch 的应用程序。

我在代码中的 2 个不同位置使用 JSON 序列化:

  • 在 REST API 的响应中。
  • 当代码与 Elasticsearch 交互时。

在 Elasticsearch 中有一些我需要的属性,但我想隐藏给应用程序用户(例如来自关系数据库的内部 ID)。

这是一个实体示例:

@Document
public class MyElasticsearchEntity {

  @Id
  private Long id; //I want to hide this to the user.
  private String name;
  private String description;
}
Run Code Online (Sandbox Code Playgroud)

问题:当对象在 Elasticsearch 中持久化时,它会被序列化为 JSON。因此,@JsonIgnore当序列化到 Elasticsearch 时,字段 with将被忽略。

到目前为止,我发现了 2 个不满意的解决方案:

解决方案 1@JsonProperty像这样使用:

@Id
@JsonProperty(access = JsonProperty.Access.READ_ONLY)
private Long id;
Run Code Online (Sandbox Code Playgroud)

id被写在Elasticsearch和JSON响应是无效:

{
  "id" : null,
  "name" : "abc",
  "description" : null
}
Run Code Online (Sandbox Code Playgroud)

所以它可以工作,但应用程序用户仍然看到这个属性存在。这很乱。

解决方案 2:自定义对象映射器以忽略空值

Spring-boot 有一个内置选项:

spring.jackson.serialization-inclusion=NON_NULL
Run Code Online (Sandbox Code Playgroud)

问题:它会抑制所有非空属性,而不仅仅是那些我想忽略的属性。假设description前一个实体的字段为空,JSON 响应将为:

{
  "name" : "abc"
}
Run Code Online (Sandbox Code Playgroud)

这对 UI 来说是有问题的。

那么有没有办法只在 JSON 响应中忽略这样的字段?

Nic*_*rot 7

您可以将Jackson JsonView用于您的目的。您可以定义一个视图,用于为应用程序用户序列化 pojo:

将视图创建为类,一个是公共的,一个是私有的:

class Views {
         static class Public { }
         static class Private extends Public { }
}
Run Code Online (Sandbox Code Playgroud)

然后使用 Pojo 中的视图作为注释:

@Id
@JsonView(Views.Private.class) String name;
private Long id;
@JsonView(Views.Public.class) String name;
private String publicField;
Run Code Online (Sandbox Code Playgroud)

然后使用视图为应用程序用户序列化您的 pojo:

objectMapper.writeValueUsingView(out, beanInstance, Views.Public.class);
Run Code Online (Sandbox Code Playgroud)

这是许多其他关于视图如何适合您的问题的示例。例如。您也可以使用objectMapper.configure(SerializationConfig.Feature.DEFAULT_VIEW_INCLUSION, false);来排除没有视图注释的字段并删除Private视图。