जैक्सन क्रमांकन: खाली मूल्यों (या अशक्त) को अनदेखा करें


138

मैं वर्तमान में जैक्सन 2.1.4 का उपयोग कर रहा हूं और जब मैं किसी JSON स्ट्रिंग में ऑब्जेक्ट को परिवर्तित कर रहा हूं, तो मुझे फ़ील्ड्स को अनदेखा करने में कुछ परेशानी हो रही है।

यहाँ मेरा वर्ग है जो परिवर्तित होने वाली वस्तु के रूप में कार्य करता है:

public class JsonOperation {

public static class Request {
    @JsonInclude(Include.NON_EMPTY)
    String requestType;
    Data data = new Data();

    public static class Data {
        @JsonInclude(Include.NON_EMPTY)
        String username;
        String email;
        String password;
        String birthday;
        String coinsPackage;
        String coins;
        String transactionId;
        boolean isLoggedIn;
    }
}

public static class Response {
    @JsonInclude(Include.NON_EMPTY)
    String requestType = null;
    Data data = new Data();

    public static class Data {
        @JsonInclude(Include.NON_EMPTY)
        enum ErrorCode { ERROR_INVALID_LOGIN, ERROR_USERNAME_ALREADY_TAKEN, ERROR_EMAIL_ALREADY_TAKEN };
        enum Status { ok, error };

        Status status;
        ErrorCode errorCode;
        String expiry;
        int coins;
        String email;
        String birthday;
        String pictureUrl;
        ArrayList <Performer> performer;
    }
}
}

और यहां बताया गया है कि मैं इसे कैसे परिवर्तित करता हूं:

ObjectMapper mapper = new ObjectMapper();
mapper.setVisibility(PropertyAccessor.FIELD, Visibility.ANY);

JsonOperation subscribe = new JsonOperation();

subscribe.request.requestType = "login";

subscribe.request.data.username = "Vincent";
subscribe.request.data.password = "test";


Writer strWriter = new StringWriter();
try {
    mapper.writeValue(strWriter, subscribe.request);
} catch (JsonGenerationException e) {
    // TODO Auto-generated catch block
    e.printStackTrace();
} catch (JsonMappingException e) {
    // TODO Auto-generated catch block
    e.printStackTrace();
} catch (IOException e) {
    // TODO Auto-generated catch block
    e.printStackTrace();
}

Log.d("JSON", strWriter.toString())

यहाँ उत्पादन है:

{"data":{"birthday":null,"coins":null,"coinsPackage":null,"email":null,"username":"Vincent","password":"test","transactionId":null,"isLoggedIn":false},"requestType":"login"}

मैं उन अशक्त मूल्यों से कैसे बच सकता हूं? मैं केवल "सदस्यता" उद्देश्य के लिए आवश्यक जानकारी लेना चाहता हूं!

यहाँ बिल्कुल वही आउटपुट है जिसकी मुझे तलाश है:

{"data":{"username":"Vincent","password":"test"},"requestType":"login"}

मैंने @JsonInclude (शामिल करें। NON_NULL) की भी कोशिश की और अपने सभी चरों को शून्य करने के लिए रखा, लेकिन यह भी काम नहीं किया! दोस्तों, आपके सहयोग के लिए धन्यवाद!


जवाबों:


247

आपके पास गलत स्थान पर एनोटेशन है - इसे कक्षा पर होना चाहिए, न कि फ़ील्ड पर। अर्थात:

@JsonInclude(Include.NON_NULL) //or Include.NON_EMPTY, if that fits your use case 
public static class Request {
  // ...
}

जैसा कि टिप्पणियों में कहा गया है, नीचे दिए गए संस्करणों में 2.x इस एनोटेशन के लिए सिंटैक्स है:

@JsonSerialize(include = JsonSerialize.Inclusion.NON_NULL) // or JsonSerialize.Inclusion.NON_EMPTY

अन्य विकल्प ObjectMapperसीधे कॉल करके कॉन्फ़िगर करना हैmapper.setSerializationInclusion(Include.NON_NULL);

(रिकॉर्ड के लिए, मुझे लगता है कि इस उत्तर की लोकप्रियता एक संकेत है कि यह एनोटेशन क्षेत्र-दर-क्षेत्र के आधार पर लागू होना चाहिए , @fasterxml)


काम करने के लिए वास्तव में कोई भी तरीका नहीं है। या NON_EMTPY एक? क्योंकि मुझे पता है कि कौन सा अशक्त होगा, लेकिन यह स्थिति पर निर्भर करता है। मैं हर वस्तु के लिए एक ही "JsonOperation" क्लास का उपयोग कर रहा हूं, जिसे मैं क्रमबद्ध / डिस्क्रिअलाइज़ करना चाहता हूं और मैं केवल उन चरों को शुरू कर रहा हूं, जिन्हें मुझे स्थिति के आधार पर उपयोग करने की आवश्यकता है। क्या यह ऐसा करने का एक अच्छा तरीका है या मुझे केवल चर की आवश्यकता वाले वर्ग को अलग-अलग करना चाहिए, जिसकी मुझे ज़रूरत है (इस तरह मुझे किसी भी एनोटेशन का उपयोग नहीं करना होगा, क्योंकि वहाँ कभी भी शून्य / खाली चर नहीं होगा)
शिनीक्स

26
सबसे हाल के संस्करण में सिंटैक्स @JsonSerialize (जिसमें = JsonSerialize.Inclusion.NON_NULL) और @JsonSerialize (शामिल = JsonSerialize.Inclusion.NON_EMPTY) शामिल हैं, यदि आपको गैर-रिक्त और गैर-रिक्त दोनों की आवश्यकता है, तो @JsonSerialize को शामिल करें। .Inclusion.NON_DEFAULT)
मेसिएज

1
कक्षा से पहले या इससे पहले कि यह काम किया संपत्ति से पहले @JsonSerialize (शामिल करें = शामिल करें। NON_NULL) का उपयोग करें ...
हंस

1
@drewmoore कृपया फिर से जाँच करें, @JsonInclude(JsonSerialize.Inclusion.NON_NULL) होना चाहिए @JsonSerialize(include=JsonSerialize.Inclusion.NON_NULL)और यह भी पुराने पदावनत तरीका है। इसलिए आपको "2.x से नीचे के संस्करण में" लिखा जाना चाहिए, "संस्करण 2 के 2.x +" में नहीं
वेस्टफ्रेमर

2
2. @JsonInclude(Include.NON_NULL)
·

48

आप वैश्विक विकल्प भी निर्धारित कर सकते हैं:

objectMapper.setSerializationInclusion(JsonInclude.Include.NON_NULL);

15

इसके अलावा आप उपयोग करने की कोशिश कर सकते हैं

@JsonSerialize(include=JsonSerialize.Inclusion.NON_NULL)

यदि आप जैकसन के साथ 2 + (1.9.5) से नीचे के संस्करण के साथ काम कर रहे हैं, तो मैंने इसका परीक्षण किया, आप इस एनोटेशन का उपयोग कक्षा के ऊपर आसानी से कर सकते हैं। केवल वर्ग घोषणा के लिए, विशेषताओं के लिए निर्दिष्ट नहीं।


2
JsonSerialize की विशेषता JsonInclude के पक्ष में संक्षिप्त है
fd8s0

2
जैसे मैंने कहा: 2 + (1.9.5) से नीचे के संस्करण के साथ जैक्सन के साथ
erhanasikoglu

सवाल एक विशेष संस्करण 2.1.4 के बारे में पूछता है
fd8s0

14

आपको जोड़ने की आवश्यकता है import com.fasterxml.jackson.annotation.JsonInclude;

जोड़ना

@JsonInclude(JsonInclude.Include.NON_NULL)

POJO के शीर्ष पर

अगर आपने POJO को नेस्ट किया है तो

@JsonInclude(JsonInclude.Include.NON_NULL)

हर मूल्यों पर जोड़ने की जरूरत है।

नोट: JAXRS (जर्सी) स्वचालित रूप से 2.6 और इसके बाद के संस्करण इस परिदृश्य को संभालती है।


पुराने org.codehaus.jackson.annotate पैकेज का उपयोग करते समय समान कार्यक्षमता है?
11:29

हां, आप गेट्टर विधि के शीर्ष पर जोड़ सकते हैं उदाहरण निजी इंट आईडी; @JsonIgnore public int getId () {रिटर्न आईडी; }
वाकर खान

1
मौजूदा उत्तरों के समान
कार्ल रिक्टर


2

मुझे हाल ही में संस्करण 2.6.6 के साथ ऐसी ही समस्या थी।

@JsonInclude(JsonInclude.Include.NON_NULL)

दायर या वर्ग स्तर पर या तो एनोटेशन का उपयोग उम्मीद के मुताबिक काम नहीं कर रहा था। जहाँ मैं एनोटेशन लागू कर रहा था, POJO परस्पर था। जब मैंने पीओजेओ के व्यवहार को अपरिवर्तनीय होने के लिए बदल दिया तो एनोटेशन ने अपना जादू चलाया।

मुझे यकीन नहीं है कि अगर इस परिवाद के नए संस्करण या पिछले संस्करणों में इसका व्यवहार समान था, लेकिन 2.6.6 के लिए निश्चित रूप से आपको काम करने के लिए एनोटेशन के लिए अपरिवर्तनीय पीओजेओ की आवश्यकता होगी।

objectMapper.setSerializationInclusion(JsonInclude.Include.NON_NULL);

उपरोक्त विकल्प विकल्प के रूप में अच्छी तरह से सीधे वैश्विक स्तर पर ObjectMapper में क्रमांकन शामिल करने के विभिन्न उत्तरों में उल्लिखित है, लेकिन मैं इसे कक्षा या दायर स्तर पर नियंत्रित करना पसंद करता हूं।

इसलिए यदि आप चाहते थे कि सभी शून्य क्षेत्र को अनदेखा किया जाए, जबकि JSON क्रमांकन तब वर्ग स्तर पर एनोटेशन का उपयोग करता है, लेकिन यदि आप चाहते हैं कि केवल कुछ फ़ील्ड एक कक्षा में अनदेखा किए जाएं, तो उन विशिष्ट फ़ील्ड का उपयोग करें। यदि आप विशिष्ट प्रतिक्रिया के लिए व्यवहार को बदलना चाहते हैं, तो रखरखाव के लिए यह अधिक पठनीय और आसान है।


2

या आप GSON [ https://code.google.com/p/google-gson/ ] का उपयोग कर सकते हैं , जहां ये अशक्त क्षेत्र स्वतः हटा दिए जाएंगे।

SampleDTO.java

public class SampleDTO {

    String username;
    String email;
    String password;
    String birthday;
    String coinsPackage;
    String coins;
    String transactionId;
    boolean isLoggedIn;

    // getters/setters
}

Test.java

import com.google.gson.Gson;

public class Test {

    public static void main(String[] args) {
        SampleDTO objSampleDTO = new SampleDTO();
        Gson objGson = new Gson();
        System.out.println(objGson.toJson(objSampleDTO));
    }
}

उत्पादन:

{"isLoggedIn":false}

मैंने gson-2.2.4 का उपयोग किया


-1

यदि आप क्रमबद्धता से बूलियन प्रकार को बाहर करना चाहते हैं तो कोड बलो मदद कर सकता है:

@JsonInclude(JsonInclude.Include.NON_ABSENT)

1
मौजूदा उत्तरों के समान
कार्ल रिक्टर
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.