जैक्सन ऑब्जेक्टमैपर की एक विशेषता है जो खाली मूल्यों को हटाने की अनुमति देती है:

class Car {
   Optional<String> ownerName;
   String manufacturer;

   public Optional<String> getOwnerName() { return ownerName; }
   public String getManufacturer() { return manufacturer; }
}

Car batMobile = new Car();
batMobile.owner = Optional.of("Batman");
batMobile.manufacturer = null;

Car stolenCar = new Car();
stolenCar.owner = Optional.empty();
stolenCar.manufacturer = "Tesla";

ObjectMapper mapper = new ObjectMapper();
mapper.setSerializationInclusion(Include.NON_ABSENT);

mapper.writeValueAsString(batMobile);
/*
{
  "ownerName": "Batman"
}
*/
mapper.writeValueAsString(stolenCar);
/*
{
  "manufacturer": "Tesla"
}
*/

इसके बजाय मैं जो चाहता हूं वह है वैकल्पिक। खाली मूल्यों को हटाया जाना है, लेकिन शून्य मान बने रहना है:

mapper.writeValueAsString(batMobile);
/*
{
  "ownerName": "Batman",
  "manufacturer": null
}
*/
mapper.writeValueAsString(stolenCar);
/*
{
  "manufacturer": "Tesla"
}
*/

और मैं चाहता हूं कि यह डीटीओ पर किसी भी टिप्पणी की आवश्यकता के बिना विश्व स्तर पर लागू हो।

3
Lauren 18 अप्रैल 2020, 11:26

1 उत्तर

सबसे बढ़िया उत्तर

यदि आप java.util.Optional का उपयोग करते हैं तो सुनिश्चित करें कि आपने com.fasterxml.jackson.datatype.jdk8.Jdk8Module मॉड्यूल पंजीकृत किया है जो अतिरिक्त धारावाहिक और deserialisers प्रदान करता है।

आपके मामले में संपत्ति के स्तर पर एनोटेशन का उपयोग करने का सबसे आसान तरीका होगा:

class Car {

    @JsonInclude(JsonInclude.Include.NON_EMPTY)
    Optional<String> ownerName;

    @JsonInclude
    String manufacturer;

    //getters, setters
}

डिफ़ॉल्ट मान Include.ALWAYS है जिसका उपयोग आपके मामले में किया जाना चाहिए।

यदि आप इसे विश्व स्तर पर करना चाहते हैं तो आपको कस्टम फ़िल्टर लागू करने और सभी मामलों को मैन्युअल रूप से जांचने की आवश्यकता है। सरल उदाहरण:

class CustomFilter {

    @Override
    public boolean equals(Object obj) {
        // return false to keep value in response
        // return true to filter out value from response
        if (obj == null) {
            return false;
        }
        if (obj instanceof Optional) {
            Optional opt = (Optional) obj;
            return !opt.isPresent();
        }
        //other cases if needed

        return false;
    }
}

आप इसे नीचे के रूप में पंजीकृत कर सकते हैं:

ObjectMapper mapper = new ObjectMapper();
mapper.enable(SerializationFeature.INDENT_OUTPUT);
mapper.registerModule(new Jdk8Module());
mapper.setDefaultPropertyInclusion(JsonInclude.Value.construct(JsonInclude.Include.CUSTOM, JsonInclude.Include.CUSTOM, CustomFilter.class, CustomFilter.class));

मामले में, यह वह नहीं है जो आप चाहते थे कि आपको विश्व स्तर पर सबसे उपयुक्त मूल्य निर्धारित करने की आवश्यकता हो और दी गई संपत्तियों के लिए एक और मूल्य निर्धारित किया जाए। यदि आप DTO कक्षाओं को संशोधित नहीं कर सकते हैं, तो आप हमेशा MixIn सुविधा का उपयोग कर सकते हैं।

1
Michał Ziober 21 अप्रैल 2020, 09:08