传递给 Jersey + Jackson 时从实体中删除一个字段

Remove a field from entity when passing to Jersey + Jackson

我正在使用 Jersey + Jackson(内置于 Dropwizard)来创建一系列网络服务。我通过将对象传递给 Jersey 中的 Response 对象来直接映射 Json 中的对象:

myObject object = new myObject(fields...);
return Response.ok(object).build();

myObject class 中的字段已使用 JsonProperty("fieldName").

正确注释

但是,如果我有一个字段需要存储到数据库(例如:密码哈希),但我不想传递请求响应,那么在将实体传递给响应对象?

我不能用 JsonIgnore 注释该字段,否则当我将 Json 映射到数据库 (ElasticSearch) 时,该字段根本不会被序列化。

一个选项是简单地将字段设置为 null。要将 ObjectMapper 配置为在字段为 null 时完全忽略 JSON 中的字段,您只需执行

@Override
public void run(YourConfiguration configuration,
        Environment environment) throws Exception {
    ...
    environment.getObjectMapper().setSerializationInclusion(Include.NON_NULL);
}

顺便说一句,这个安全原因是使用 DTO(数据传输对象)的原因之一,一个额外的实体 "view" 层将我们发送的表示与持久层(db 实体对象)分开).使用 same/similar 属性创建另一个对象似乎是多余的,但安全填充是值得的。

此外,虽然还不是正式版本,Dropwizard 0.8.0 uses Jersey 2, which introduced Entity Filtering 允许我们过滤掉不想发送的数据,而无需创建 DTO。只是想我会提到它。

您应该同时使用 JsonIgnore 和 JsonProperty 来实现此目的。

  public class User {

  private String name;
  private String password;

  @JsonProperty    
  public void setPassword(String password) {
    this.password = password;
  }

  @JsonIgnore
  public String getPassword() {
    return this.password;
  }

}

@JsonProperty on setter 方法将用于序列化,JsonIgnore on getter 方法将用于反序列化。

实际上@Manikandan 的回答应该适合您。参见 Only using @JsonIgnore during serialization, but not deserialization

在最坏的情况下,您可能会尝试实现 JsonSerializer。

public class MyObjectSerializer extends JsonSerializer<MyObject> {

    @Override
    public void serialize(MyObject value, JsonGenerator jgen, SerializerProvider provider) throws IOException, JsonProcessingException {
        jgen.writeStartObject();
        jgen.writeString(value.getField1());
        jgen.writeString(value.getField2());
        /* and not include field that you don't want to serialize */
        jgen.writeEndObject();
    }

}

@JsonSerialize(using = MyObjectSerializer.class)
public class MyObject {

    String field1;
    Integer field2;
    String fieldNotToBeSerialized;

    public String getField1() {
        return field1;
    }
    public void setField1(String field1) {
        this.field1 = field1;
    }
    public Integer getField2() {
        return field2;
    }
    public void setField2(Integer field2) {
        this.field2 = field2;
    }
    public String getFieldNotToBeSerialized() {
        return fieldNotToBeSerialized;
    }
    public void setFieldNotToBeSerialized(String fieldNotToBeSerialized) {
        this.fieldNotToBeSerialized = fieldNotToBeSerialized;
    }

}