有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

java在传递到Jersey+Jackson时从实体中删除字段

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

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

字段在myObject类中使用JsonProperty(“fieldName”)正确注释

但是,如果我有一个字段需要存储到数据库(例如:密码散列),但我不想传入请求响应,那么在将实体传递到响应对象时如何删除该字段

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


共 (3) 个答案

  1. # 1 楼答案

    事实上,@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;
        }
    
    }
    
  2. # 2 楼答案

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

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

    另一方面,这种安全性是使用DTO(数据传输对象)的原因之一,DTO是一个额外的实体“视图”层,它将我们发送的表示与持久性层(db实体对象)分离。创建另一个具有相同/相似属性的对象似乎是多余的,但安全填充是值得的

    另外,虽然还不是正式发布,但是Dropwizard 0.8.0使用了Jersey 2,它引入了Entity Filtering,允许我们过滤掉我们不想发送的数据,而无需创建DTO。我只是想提一下

  3. # 3 楼答案

    您应该同时使用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;
      }
    
    }
    

    setter方法上的@JsonProperty将用于序列化&;getter方法上的JsonIgnore将用于反序列化