2012-09-26 43 views
10

我有以下注釋的類:州/傑克遜@JsonIgnore上二傳手

class A { 
public Map<String,List<String>> references; 

@JsonProperty 
public Map<String,List<String>> getReferences() { 
... 
} 

@JsonIgnore 
public void setReferences(Map<String,List<String>>) { 
} 
... 
} 
} 

我嘗試是忽略對反序列化JSON的。但它不起作用。總是當JSON字符串到達​​時,Jackson lib填充參考屬性。如果我僅使用@JsonIgnore註釋,getter不起作用。有沒有解決這個問題的方法?

感謝

回答

0

我只能想到一個非傑克遜的解決方案,要使用不具有映射參考,然後轉換爲實際的類的基類:

// expect a B on an incoming request 
class B { 
// ... 
} 

// after the data is read, cast to A which will have empty references 
class A extends B { 
public Map<String,List<String>> references; 
} 

爲什麼如果你不想要它們,你甚至會發送參考文獻?

或者傳入的數據不在您的手中,您只是想避免映射異常,告訴您傑克遜無法找到用於設置傳入引用的屬性?爲此,我們使用一個基類,所有我們的Json模型類的繼承:

public abstract class JsonObject { 

    @JsonAnySetter 
    public void handleUnknown(String key, Object value) { 

     // for us we log an error if we can't map but you can skip that 
     Log log = LogFactory.getLog(String.class);  
     log.error("Error mapping object of type: " + this.getClass().getName());  
     log.error("Could not map key: \"" + key + "\" and value: \"" + "\"" + value.toString() + "\""); 

    } 

然後在POJO添加@JsonIgnoreProperties,使引入屬性將被轉發到handleUnknown()

@JsonIgnoreProperties 
class A extends JsonObject { 
    // no references if you don't need them 
} 

編輯

This SO Thread描述瞭如何使用Mixins。這可能是解決方案,如果你想保持你的結構完全一樣,但我沒有嘗試過。

+0

這是正確的。傳入的數據並不在我們手中。但客戶端總是以正確的格式發送引用屬性,所以handleUnknown永遠不會被調用。 – guerilla

+0

啊,我的不好,忘了一點信息。如果您想忽略傳入數據,您需要在POJO上使用'@ JsonIgnoreProperties'。我會更新我的帖子。 (PS:我們使用它來消費Facebook的REST資源,並且從Facebook發送的所有不包含在我們的POJO中的屬性將被記錄下來,然後我們決定是否要添加它們) – Pete

+0

但是引用在我的POJO中總是與制定者匹配 – guerilla

15

我認爲有兩個關鍵部分應該使您能夠根據需要擁有「只讀集合」。首先,除了忽略二傳手,確保您還標有@JsonIgnore

class A { 

    @JsonIgnore 
    public Map<String,List<String>> references; 

    @JsonProperty 
    public Map<String,List<String>> getReferences() { ... } 

    @JsonIgnore 
    public void setReferences(Map<String,List<String>>) { ... } 

} 

其次,爲了防止吸氣劑被用作制定者,禁用USE_GETTERS_AS_SETTERS功能:

ObjectMapper mapper = new ObjectMapper(); 
mapper.disable(MapperFeature.USE_GETTERS_AS_SETTERS); 
+0

我愚蠢地忽略了您的第一條建議,並未將該字段標記爲忽略,因爲它對我而言屬於私有。不過,我需要這樣做,才能正常工作。這是對的還是對我的誤解?如果是這樣,也許值得在答案中明確指出。 –

4

您必須確保在字段級別以及setter上有@JsonIgnore註釋,並使用@JsonProperty註釋getter。

public class Echo { 

    @Null 
    @JsonIgnore 
    private String doNotDeserialise; 

    private String echo; 

    @JsonProperty 
    public String getDoNotDeserialise() { 
     return doNotDeserialise; 
    } 

    @JsonIgnore 
    public void setDoNotDeserialise(String doNotDeserialise) { 
     this.doNotDeserialise = doNotDeserialise; 
    } 

    public String getEcho() { 
     return echo; 
    } 

    public void setEcho(String echo) { 
     this.echo = echo; 
    } 
} 

@Controller 
public class EchoController { 

@ResponseBody 
@RequestMapping(value = "/echo", consumes = APPLICATION_JSON_VALUE, produces = APPLICATION_JSON_VALUE) 
    public Echo echo(@RequestBody @Valid Echo echo) { 
     if (StringUtils.isEmpty(echo.getDoNotDeserialise())) { 
      echo.setDoNotDeserialise("Value is set by the server, not by the client!"); 
     } 

     return echo; 
    } 
} 
  • 如果您提交設置爲東西「doNotDeserialise」值,當JSON是deserialised它會被設置爲null對象的JSON請求(如果不是我把驗證約束的字段,以便它會出錯誤)
  • 如果在「doNotDeserialise」值設置到服務器,然後將正確的序列化JSON的東西推到客戶端
3

我在我的getter使用@JsonIgnore,它沒」 t工作,我無法配置映射器(我w如使用傑克遜傑克遜提供者)。這爲我工作:

@JsonIgnoreProperties(ignoreUnknown = true, value = { "actorsAsString", 
    "writersAsString", "directorsAsString", "genresAsString" }) 
0

由於傑克遜2.6的,有使用JsonProperty#access()註釋定義read-onlywrite-only特性,一個新的和改進的方式。推薦使用單獨的JsonIgnoreJsonProperty註釋。

@JsonProperty(access = JsonProperty.Access.READ_ONLY) 
public Map<String,List<String>> references;