জ্যাকসন সিরিয়ালাইজেশন: খালি মানগুলি উপেক্ষা করুন (বা নাল)


138

আমি বর্তমানে জ্যাকসন ২.১.৪ ব্যবহার করছি এবং যখন আমি কোনও জেসসন স্ট্রিংয়ে কোনও অবজেক্টটি রূপান্তর করছি তখন ক্ষেত্রগুলি উপেক্ষা করার ক্ষেত্রে আমার কিছুটা সমস্যা হচ্ছে।

এখানে আমার ক্লাস যা রূপান্তরিত করার জন্য বস্তু হিসাবে কাজ করে:

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

আমি @ জসনআইনক্লুডও (অন্তর্ভুক্ত করুন। NON_NULL) চেষ্টা করেছিলাম এবং আমার সমস্ত ভেরিয়েবলগুলি বাতিল করে দিয়েছি, তবে এটি কার্যকর হয়নি! আপনার সাহায্যের জন্য ধন্যবাদ বন্ধুরা!


উত্তর:


247

আপনার কাছে ভুল জায়গায় টিকা আছে - এটি ক্লাসে থাকা দরকার, ক্ষেত্র নয়। অর্থাৎ,

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

মন্তব্যে উল্লিখিত হিসাবে, ২.x নীচের সংস্করণগুলিতে এই টীকায়নের সিনট্যাক্সটি হ'ল:

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

অন্য বিকল্পটি হ'ল ObjectMapperসরাসরি ফোন করে সরাসরি কনফিগার করাmapper.setSerializationInclusion(Include.NON_NULL);

(রেকর্ডের জন্য, আমি মনে করি যে এই উত্তরের জনপ্রিয়তা একটি সূত্র যে এই টীকাগুলি একটি ক্ষেত্রের ভিত্তিতে মাঠের ভিত্তিতে প্রয়োগ করা উচিত, @ ফার্স্টেক্সএমএল)


অন্তর্ভুক্ত করার সত্যিই কোন উপায় নেই N বা NON_EMTPY এক? কারণ আমি জানি কোনটি নাল হবে, তবে এটি পরিস্থিতির উপর নির্ভর করে। আমি সিরিয়ালাইজেশন / ডিসরিয়ালাইজ করতে চাই এমন প্রতিটি বস্তুর জন্য আমি একই "জসনঅপ্রেশন" শ্রেণিটি ব্যবহার করছি এবং আমি কেবলমাত্র পরিস্থিতির উপর নির্ভর করে আমার যে পরিবর্তনশীলগুলি ব্যবহার করতে হবে তা কেবল চালু করছি। এটি করার কি এটি একটি ভাল উপায় বা আমার কেবলমাত্র প্রয়োজনীয় ভেরিয়েবলগুলি সহ বহুবিধ ক্লাস করা উচিত (সেভাবে আমাকে কোনও টিকা ব্যবহার করতে হবে না, যেহেতু কখনই কোনও নাল / ফাঁকা ভেরিয়েবল থাকবে না)
শিনিক্স

26
সিনট্যাক্সটি বেশিরভাগ সাম্প্রতিক সংস্করণে @ জসনসরিয়ালাইজে পরিবর্তিত হয়েছে (অন্তর্ভুক্ত = জসনসরিয়ালাইজ করুন nc .Inclusion.NON_DEFAULT)
Maciej

1
@JsonSerialize ব্যবহার (অন্তর্ভুক্ত = Inclusion.NON_NULL) বর্গ আগে বা সম্পত্তি সামনে এটা কাজ ...
রাজহাঁস

1
@ ড্রমুওরে দয়া করে আবার যাচাই করুন, এটি @JsonInclude(JsonSerialize.Inclusion.NON_NULL) হওয়া উচিত @JsonSerialize(include=JsonSerialize.Inclusion.NON_NULL)এবং এটিও পুরানো অবহেলিত উপায়। সুতরাং আপনার "2.x নীচের সংস্করণে" লিখতে হবে, "সংস্করণ 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
জসনসিরালাইজ এর বৈশিষ্ট্য অন্তর্ভুক্ত করা হয়েছে জসনআইনক্লুডের পক্ষে অবমাননিত
fd8s0

2
যেমন আমি বলেছি: 2+ (1.9.5) এর নীচে সংস্করণ সহ জ্যাকসনের সাথে
এরহানাসিকোগলু

প্রশ্নটি একটি বিশেষ সংস্করণ সম্পর্কে জিজ্ঞাসা করে 2.1.4
fd8s0

14

আপনি যোগ করা প্রয়োজন import com.fasterxml.jackson.annotation.JsonInclude;

যোগ

@JsonInclude(JsonInclude.Include.NON_NULL)

POJO শীর্ষে

আপনি যদি POJO নেস্ট করে থাকেন তবে

@JsonInclude(JsonInclude.Include.NON_NULL)

প্রতিটি মান যুক্ত করতে হবে।

দ্রষ্টব্য: JAXRS (জার্সি) স্বয়ংক্রিয়ভাবে এই দৃশ্যটি ২.6 বা তারও বেশি উপরে পরিচালনা করে।


পুরানো org.codehaus.jackson.annotate প্যাকেজটি ব্যবহার করার সময় কি একই রকম কার্যকারিতা রয়েছে?
pkran

হ্যাঁ, আপনি গেটর পদ্ধতির শীর্ষে ব্যক্তিগত ব্যক্তিগত আইডি যুক্ত করতে পারেন; @ জসন পাবলিক ইন গেট আইডি () {রিটার্ন আইডি উপেক্ষা করুন; }
ভাকুয়ার খান

1
বিদ্যমান উত্তর হিসাবে একই
কার্ল রিখটার


2

ভার্সন ২.6.। নিয়ে আমার সম্প্রতি একই সমস্যা হয়েছিল similar

@JsonInclude(JsonInclude.Include.NON_NULL)

দায়েরকৃত বা শ্রেণির স্তরের উপরের টীকাগুলি ব্যবহার করা প্রত্যাশার মতো কাজ করছে না। আমি টীকাটি প্রয়োগ করছিলাম সেখানে POJO পরিবর্তনযোগ্য ছিল। যখন আমি POJO এর আচরণ পরিবর্তন করে অস্থির হয়ে উঠতে টীকাটি তার যাদুতে কাজ করে।

আমি নিশ্চিত নই যে এটির নতুন সংস্করণে বা পূর্ববর্তী সংস্করণগুলির পূর্ববর্তী সংস্করণগুলির একই রকম আচরণ হয়েছে তবে ২.6..6 এর জন্য অবশ্যই টীকাটি কাজ করার জন্য আপনার অপরিবর্তনীয় পোজো থাকা দরকার।

objectMapper.setSerializationInclusion(JsonInclude.Include.NON_NULL);

ওবজেক্টম্যাপারে সিরিয়ালাইজেশন অন্তর্ভুক্তি নির্ধারণের বিভিন্ন উত্তরে উপরে উল্লিখিত বিকল্পগুলি সরাসরি বিশ্বস্তরে কাজ করে তবে, আমি শ্রেণি বা দায়েরকৃত স্তরে এটি নিয়ন্ত্রণ করতে পছন্দ করি।

সুতরাং আপনি যদি JSON সিরিয়ালাইজেশনের সময় সমস্ত নাল ক্ষেত্রকে অগ্রাহ্য করতে চান তবে ক্লাস পর্যায়ে টীকাগুলি ব্যবহার করুন তবে আপনি যদি কেবলমাত্র কয়েকটি ক্ষেত্রকে কোনও শ্রেণিতে উপেক্ষা করতে চান তবে সেই নির্দিষ্ট ক্ষেত্রগুলির মধ্যে এটি ব্যবহার করুন। আপনি যদি নির্দিষ্ট প্রতিক্রিয়ার জন্য আচরণটি পরিবর্তন করতে চান তবে এটি এর আরও পাঠযোগ্য এবং রক্ষণাবেক্ষণের পক্ষে সহজ।


2

অথবা আপনি জিএসএন [ 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
বিদ্যমান উত্তর হিসাবে একই
কার্ল রিখটার
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.