2015-01-08 44 views
0

我使用Jersey + Jackson(內置於Dropwizard中)創建一系列Web服務。我通過將它們傳遞到響應對象中澤西直接映射在JSON對象:傳遞給Jersey + Jackson時從實體中刪除字段

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

域被正確地註釋中myObject的類JsonProperty(「fieldName的」)。但是,如果我有一個字段,我需要存儲到數據庫(例如:密碼哈希),但我不想傳入請求響應,我怎麼能刪除該字段時,將實體傳遞給響應目的?

我不能使用JsonIgnore註釋該字段,否則當我將Json映射到數據庫(ElasticSearch)時,該字段根本不會被序列化。

回答

2

一種選擇是簡單地將字段設置爲null。要配置ObjectMapper完全忽略該領域的JSON當字段爲空,你可以做

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

順便說一句,此安全原因的原因之一來使用的DTO(數據傳輸對象),一個額外的實體「視圖」層,它將我們從持久層(db實體對象)發出的表示分開。使用相同/相似的屬性創建另一個對象似乎是多餘的,但安全填充是值得的。

此外,儘管尚未正式發佈,但Dropwizard 0.8.0使用了Jersey 2,它引入了Entity Filtering,它允許我們過濾掉我們不想發送的數據,而無需創建DTO。只是想我會提到它。

+0

謝謝;我從來沒有使用實體過濾,但我認爲這是實現我所需要的最好方法。你能否提供一個Dropwizard中實體過濾的例子(我正在使用DW 0.8.0-rc1)?實體過濾只能在單個資源/路徑上工作,而不是在全局應用程序級上工作嗎? –

+0

我剛剛意識到它目前不支持Jackson。我一直在試圖實現一些東西,但這並不是微不足道的。我想說的是用一個DTO或將其設置爲空。如果您想要更優雅的解決方案(不必在資源方法中將字段設置爲null),則可以使用JAX-RS攔截器,但在執行此操作之前,我會考慮兩次。有些東西像密碼一樣安全,我會盡可能遠離最終進程 –

+1

DTO對象+1。 – Natan

0

您應該使用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上設置器方法,將在序列&使用JsonIgnore上的吸氣劑的方法將在反序列化使用。

+0

謝謝,但在這種情況下,即使在應用程序「內部」,我也不會獲得密碼字段;我需要它在登錄時驗證用戶。 –

+0

你是什麼意思的「內部」的應用程序。您可以直接在應用程序中使用對象。它將有密碼值。 – Manikandan

+0

我直接在JS上存儲對象。如果我添加JsonIgnore來獲取;當我將對象映射到JSON時,我將在更新時丟失密碼字段。 –

0

其實@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; 
    } 

}