2012-09-26 18 views
10

पर मैं निम्नलिखित एनोटेशन के साथ एक वर्ग है। लेकिन यह काम नहीं करता है। हमेशा जब JSON स्ट्रिंग जैक्सन lib आता है संदर्भ संदर्भ भरें। अगर मैं केवल @ जेसन इग्नोर एनोटेशन का उपयोग करता हूं तो गेटर काम नहीं करता है। क्या इस समस्या के लिए कोई समाधान है?जर्सी/जैक्सन @JsonIgnore सेटर

धन्यवाद

उत्तर

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; 
} 

क्यों यदि आप उन्हें नहीं चाहते हैं तो आप संदर्भ भी भेजते हैं?

या आपके हाथों से आने वाला डेटा है और आप बस मैपिंग अपवाद से बचना चाहते हैं जो आपको बता रहा है कि जैक्सन आने वाले संदर्भों के लिए सेट करने के लिए कोई संपत्ति नहीं ढूंढ सकता है?

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 
} 

के पास भेज हो जाएगी: कि के लिए हम एक आधार वर्ग है जो हमारे Json मॉडल वर्गों के सभी के वारिस का उपयोग संपादित करें

This SO Thread मिक्सिन का उपयोग करने का वर्णन करता है। यह समाधान हो सकता है, अगर आप अपनी संरचना को ठीक तरह से रखना चाहते हैं, लेकिन मैंने कोशिश नहीं की है।

+0

यह सही है। आने वाला डेटा वास्तव में हमारे हाथों में नहीं है। लेकिन ग्राहक हमेशा सही प्रारूप में संदर्भ गुण भेजते हैं ताकि संभाल अज्ञात कभी नहीं कहा जाएगा। – guerilla

+0

आह, मेरा बुरा, जानकारी का एक छोटा सा टुकड़ा भूल गया। यदि आप आने वाले डेटा को अनदेखा करना चाहते हैं तो आपको POJO पर '@ JsonIgnoreProperties 'की आवश्यकता है। मैं अपनी पोस्ट अपडेट करूंगा। (पीएस: हम इसका इस्तेमाल फेसबुक के आरईएसटी संसाधन का उपभोग करने के लिए करते हैं और फेसबुक से भेजे गए सभी गुण जो हमारे पीओजेओ में शामिल नहीं हैं, सिर्फ लॉग इन होंगे और फिर हम तय करेंगे कि हम उन्हें जोड़ना चाहते हैं या नहीं) – 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

आपको यह सुनिश्चित करना होगा कि क्षेत्र स्तर पर और साथ ही सेटटर पर @ जेसन इग्नोर एनोटेशन और @ जेसनप्रोपर्टी के साथ एनोटेटेड गेटटर है।

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 है के साथ एक JSON अनुरोध सबमिट करते हैं (नहीं तो मैं बहुत मैदान पर एक सत्यापन बाधा डाल इसे बाहर त्रुटि जाएगा)
  • आप सर्वर तो इसे सही ढंग से JSON करने के लिए धारावाहिक की जाएगी पर कुछ करने के लिए "doNotDeserialise" मान सेट और ग्राहक
3

मैं अपने गेटर पर @JsonIgnore इस्तेमाल किया की ओर धकेल दिया है और उसे नहीं था ' टी काम नहीं करता और मैं मैपर को कॉन्फ़िगर नहीं कर सका (मैं डब्ल्यू जैक्सन जैक्सर्स प्रदाताओं का उपयोग करने के रूप में)।यह मेरे लिए काम किया:

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

जैक्सन 2.6 के रूप में, है JsonProperty#access() एनोटेशन का उपयोग कर, read-only और write-only गुण परिभाषित करने के लिए एक नया और बेहतर तरीका है। यह अलग JsonIgnore और JsonProperty एनोटेशन के उपयोग पर अनुशंसित है।

@JsonProperty(access = JsonProperty.Access.READ_ONLY) 
public Map<String,List<String>> references; 
संबंधित मुद्दे