2012-02-21 37 views
11

是否有可能有選擇地確定何時在運行時使用@JsonFilter註釋?@JsonFilter引發「JsonMappingException:無法解析BeanPropertyFilter」

我得到JsonMappingException異常(見下文),當我不提供過濾器。

背景:

我從recent StackOverflow post,我可以使用@JsonFilter動態過濾bean屬性得到序列化的經驗教訓。這很好。加入@JsonFilter("apiFilter")我的域類並加入這個代碼在我的JAX-RS服務(使用CXF實現)後,我能夠動態地過濾由我的RESTful API返回的屬性:

// shortened for brevity 
FilterProvider filters = new SimpleFilterProvider().addFilter("apiFilter", SimpleBeanPropertyFilter.filterOutAllExcept(filterProperties)); 

return mapper.filteredWriter(filters).writeValueAsString(user); 

問題是否有不同的服務電話,我根本不想應用過濾器。在這些情況下,我想返回整個域類而不過濾任何屬性。在情況下我只是想回到我得到一個異常如下域類:

Caused by: org.codehaus.jackson.map.JsonMappingException: Can not resolve BeanPropertyFilter with id 'apiFilter'; no FilterProvider configured 

at org.codehaus.jackson.map.ser.BeanSerializer.findFilter(BeanSerializer.java:252) 
at org.codehaus.jackson.map.ser.BeanSerializer.serializeFieldsFiltered(BeanSerializer.java:216) 
at org.codehaus.jackson.map.ser.BeanSerializer.serialize(BeanSerializer.java:140) 

回答

6

我想你可以欺騙過濾筆者定義的情況下,空濾連載要將所有屬性seralized:

FilterProvider filters = new SimpleFilterProvider().addFilter("apiFilter", SimpleBeanPropertyFilter.serializeAllExcept(emptySet)); 

這樣,當發動機查找在@JsonFilter anotation定義的「apiFilter」過濾器,它發現它,但它不會有任何影響(如將序列的所有屬性)。

編輯 此外,您還可以調用工廠方法writer()而不是filteredWriter()

ObjectWriter writer=null; 
if(aplyFilter) { 
    FilterProvider filters = new SimpleFilterProvider().addFilter("apiFilter", SimpleBeanPropertyFilter.filterOutAllExcept(filterProperties)); 
    writer=mapper.filteredWriter(filters); 
} else { 
    writer=mapper.writer(); 
} 

return writer.writeValueAsString(user); 

我想這最後的解決辦法是更清潔的方式,的確更好。

+0

在我編輯的例子中,我是否需要包含代碼以檢查在每個jax-rs服務調用中調用哪個編寫器方法?在一些服務方法中,我返回實際的用戶對象而不是字符串。非常感謝您的意見! – Justin 2012-02-21 18:29:47

+1

好的,我有機會嘗試一下。你提出的「竅門」有效,但我無法得到你的第二個「更清潔」的建議。在這種情況下,我仍然收到「沒有FilterProvider配置」錯誤。再次感謝。 – Justin 2012-02-21 22:31:28

+0

@Justin:好吧,IMO解決問題的「不潔淨」解決方法比「乾淨」的不工作:)更好。希望它有助於解決您的問題。 – 2012-02-22 08:33:22

18

我知道這已經回答了,但對於任何newcommers傑克遜實際上已經加入到不缺少過濾器(JACKSON-650)失敗的能力:
你只需要調用 SimpleFilterProvider.setFailOnUnknownId(false),你不會得到這個例外。

+0

謝謝你的回答。這是有幫助的 – Justin 2012-03-20 13:09:48

+4

當然,即使您不打算使用所使用的映射器進行過濾,您仍然需要配置SimpleFilterProvider。好吧。 – Jules 2013-11-19 22:45:09

0

我有一個類似的問題得到相同的例外,但接受的答案並沒有真正幫助我的情況。下面是對我工作的解決方案:

在我的設置,我使用自定義JacksonSerializer這樣的:

@JsonSerialize(using = MyCustomSerializer.class) 
private Object someAttribute; 

這串是這樣實現的:

public class MyCustomSerializer extends JsonSerializer<Object> { 
    @Override 
    public void serialize(Object o, JsonGenerator jgen, SerializerProvider provider) throws IOException, JsonProcessingException { 
    if (o != null) { 
     jgen.writeObject(o); 
    } 
    } 
} 

與此問題是,只要你不使用任何過濾器,它的作品。它也適用於序列化原語,例如,如果使用jgen.writeString(..)。如果您使用過濾器,則代碼錯誤,因爲過濾器存儲在SerializerProvider內部的某處,而不是JsonGenerator。如果在這種情況下直接使用jsongenerator,則會在內部創建一個不知道過濾器的新SerializerProvider。因此,您需要撥打provider.defaultSerializeValue(o, jgen)而不是較短的jgen.writeObject(o)。這將確保過濾器不會丟失並且可以被應用。

相關問題