2012-02-21 3 views
11

क्या यह चुनना संभव है कि @JsonFilter एनोटेशन रनटाइम पर कब उपयोग किया जाए?@ जेसनफ़िल्टर फेंकता है "जेसन मैपिंग अपवाद: बीनप्रॉपर्टीफिल्टर को हल नहीं कर सकता"

जब मैं फ़िल्टर प्रदान नहीं करता हूं तो मुझे जेसन मैपिंग अपवाद अपवाद (नीचे देखें) मिल रहा है।

पृष्ठभूमि:

मैं एक recent StackOverflow post कि मैं @JsonFilter उपयोग कर सकते हैं गतिशील रूप से सेम गुण धारावाहिक हो रही फिल्टर करने के लिए से सीखा है। यह बहुत अच्छा काम करता है।

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

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

समस्या: मेरे डोमेन वर्ग के लिए और मेरे jax-रु सेवा में इस कोड (CXF कार्यान्वयन का उपयोग) के अलावा के साथ @JsonFilter("apiFilter") जोड़ने के बाद, मैं गतिशील गुण मेरी RESTful API द्वारा फिल्टर करने के लिए कर रहा हूँ क्या अलग-अलग सेवा कॉल हैं जहां मैं फ़िल्टर को बिल्कुल लागू नहीं करना चाहता हूं। उन मामलों में मैं किसी भी संपत्ति को फ़िल्टर किए बिना पूरे डोमेन क्लास को वापस करना चाहता हूं।

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

मुझे लगता है कि आप फ़िल्टर लेखक के मामलों के लिए एक खाली serialize फिल्टर को परिभाषित धोखा हो सकता है जहाँ आप सभी गुण हैं: उस मामले में जहां मैं सिर्फ डोमेन वर्ग इस प्रकार मैं एक अपवाद हो रही है वापस जाने के लिए कोशिश seralized:

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

इस तरह, जब इंजन "apiFilter" फिल्टर @JsonFilter एनोटेशन में परिभाषित के लिए लग रहा है, यह यह पाता है, लेकिन यह कोई असर नहीं होगा (के रूप में सभी गुण को क्रमानुसार जाएगा)।

संपादित इसके अलावा, आप कारखाने विधि 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

आपके संपादित उदाहरण में, क्या मुझे यह कोड जांचने की आवश्यकता होगी कि प्रत्येक जैक्स-आरएस सेवा कॉल में कौन सी लेखक विधि कॉल करें? कुछ सेवा विधियों में मैं स्ट्रिंग के बजाए एक वास्तविक उपयोगकर्ता ऑब्जेक्ट देता हूं। आपके इनपुट के लिए बहुत धन्यवाद! – Justin

+1

ठीक है, मुझे इसे आज़माने का मौका मिला। आपके द्वारा सुझाए गए "चाल" का काम करता है लेकिन मुझे काम करने के लिए आपका दूसरा "क्लीनर" सुझाव नहीं मिल सका। उस स्थिति में मुझे अभी भी "कोई फ़िल्टरप्रोवाइडर कॉन्फ़िगर नहीं किया गया" त्रुटि प्राप्त होती है। एक बार फिर धन्यवाद। – Justin

+0

@ जस्टिन: ठीक है, आईएमओ एक "अशुद्ध" कामकाज जो समस्या हल करता है एक "साफ" से बेहतर है जो काम नहीं कर रहा है :)। उम्मीद है कि यह आपकी समस्या को हल करने में मदद करता है। –

18

मैं जानता हूँ कि यह पहले से ही उत्तर दिया गया है, लेकिन किसी भी newcommers के लिए जैक्सन वास्तव में क्षमता लापता फिल्टर (JACKSON-650) पर असफल नहीं करने के लिए जोड़ा गया है:
तुम बस SimpleFilterProvider.setFailOnUnknownId(false) कॉल करने के लिए की जरूरत है और आप इस अपवाद नहीं मिलेगा।

+0

आपके उत्तर के लिए धन्यवाद। यह उपयोगी है – Justin

+4

बेशक आपको अभी भी एक सरलफिल्टरप्रोवाइडर को कॉन्फ़िगर करने की आवश्यकता है, भले ही आप जिस मैपर का उपयोग कर रहे हैं उसके साथ फ़िल्टरिंग का उपयोग नहीं कर रहे हों। ओह अच्छा। – Jules

0

मुझे एक ही अपवाद प्राप्त करने में एक समान समस्या थी, लेकिन स्वीकृत उत्तर वास्तव में मेरे मामले में मदद नहीं करता था।

मेरी सेटअप में मैं इस तरह एक कस्टम JacksonSerializer उपयोग कर रहा था:: यहाँ समाधान है कि मेरे लिए काम किया है

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

और वह serializer इस तरह लागू किया गया था:

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, जो फ़िल्टर के बारे में नहीं जानता है, आंतरिक रूप से बनाया गया है। तो छोटे jgen.writeObject(o) के बजाय आपको provider.defaultSerializeValue(o, jgen) पर कॉल करने की आवश्यकता है।इससे यह सुनिश्चित होगा कि फ़िल्टर खो नहीं जाते हैं और इसे लागू किया जा सकता है।

संबंधित मुद्दे