জ্যাকসন 'ইজ' অপসারণ করে আদিম বুলেটিয়ান ফিল্ডটির নামকরণ করেছেন


93

এটি একটি সদৃশ হতে পারে। তবে আমি আমার সমস্যার সমাধান খুঁজে পাচ্ছি না।

আমার একটা ক্লাস আছে

public class MyResponse implements Serializable {

    private boolean isSuccess;

    public boolean isSuccess() {
        return isSuccess;
    }

    public void setSuccess(boolean isSuccess) {
        this.isSuccess = isSuccess;
    }
}

গ্রীকস এবং সেটারগুলি গ্রহন দ্বারা উত্পাদিত হয়।

অন্য ক্লাসে, আমি মানটিকে সত্যে সেট করেছিলাম এবং এটি JSON স্ট্রিং হিসাবে লিখি।

System.out.println(new ObjectMapper().writeValueAsString(myResponse));

জেএসনে, কীটি আসছে {"success": true}

আমি চাবিটি isSuccessনিজের মতো করে চাই। সিরিয়ালাইজেশন করার সময় জ্যাকসন কি সেটার পদ্ধতি ব্যবহার করছেন? কীভাবে ক্ষেত্রের নাম নিজেই তৈরি করবেন?


4
আপনার সম্পত্তির নামটি যদি আপনার মত থাকে তবে আপনার নামটির isSuccessনাম অবশ্যই isIsSuccessমনে করা উচিত
জেনস

আমি বুঝেছি. আমি ভেবেছিলাম এটি SetSuccess গ্রহণের দ্বারা উত্পন্ন হওয়ার সাথে সাথে এটি আরও ভাল । (একটি মান অনুসরণ করে)
আইকোড

উত্তর:


119

এটি কিছুটা দেরি করে দেওয়া উত্তর, তবে এই পৃষ্ঠায় আসা অন্য যে কোনও ব্যক্তির পক্ষে এটি কার্যকর হতে পারে।

জ্যাকসন সিরিয়াল করার সময় জ্যাকসন যে নামটি ব্যবহার করবেন তা পরিবর্তনের একটি সহজ সমাধান হ'ল @ জসনপ্রপার্টি টীকাটি ব্যবহার করুন , সুতরাং আপনার উদাহরণটি হয়ে উঠবে:

public class MyResponse implements Serializable {

    private boolean isSuccess;

    @JsonProperty(value="isSuccess")        
    public boolean isSuccess() {
        return isSuccess;
    }

    public void setSuccess(boolean isSuccess) {
        this.isSuccess = isSuccess;
    }
}

এরপরে এটি JSON এ সিরিয়ালযুক্ত হবে তবে এতে {"isSuccess":true}আপনার গেটর পদ্ধতির নামটি পরিবর্তন না করার সুবিধা রয়েছে।

মনে রাখবেন যে এক্ষেত্রে আপনি @JsonProperty("isSuccess")কেবল একক valueউপাদান থাকায় এই ক্ষেত্রে আপনি টীকাটিও লিখতে পারেন


এই পদ্ধতিটি আমার ক্ষেত্রে কাজ করবে না কারণ ক্লাসটি আমার তৃতীয় পক্ষের নির্ভরতা থেকে আসে বলে ক্লাসটি আমার মালিকানাধীন নয়। যেমন ক্ষেত্রে, নীচে আমার উত্তর দেখুন।
এডমন্ডপি

4
আমি জ্যাকসনের সাথে বসন্ত বুট ব্যবহার করছি তবে দুটি ক্ষেত্র পাওয়ার একটি হ'ল "সাফল্য" এবং অন্যটি হ'ল "ইসস্যাক্সেস" এবং যখন আমি কেবলমাত্র একটি ক্ষেত্রের তুলনায় অ আদিম বুলিয়ান ব্যবহার করি "ইসস্যাক্সেস"
বিশাল

@ বিশালসিংলা আমার ঠিক একই সমস্যা রয়েছে, এই
দ্রবণটি

22

আমি সম্প্রতি এই ইস্যুতে দৌড়েছি এবং এটি আমি খুঁজে পেয়েছি। জ্যাকসন আপনি গেটার এবং সেটটারদের জন্য যে কোনও শ্রেণীর কাছে এটি পাস করেছেন তা পরীক্ষা করে দেখবেন এবং সিরিয়ালাইজেশন এবং ডিসরিয়ালাইজেশনের জন্য এই পদ্ধতিগুলি ব্যবহার করবেন। এই পদ্ধতিগুলিতে "get", "is" এবং "set" এর পরে যা JSON ফিল্ডের মূল কী হিসাবে ব্যবহার করা হবে (getIsValid এবং setIsValid এর জন্য "isValid") হবে।

public class JacksonExample {   

    private boolean isValid = false;

    public boolean getIsValid() {
        return isValid;
    }

    public void setIsValid(boolean isValid) {
        this.isValid = isValid;
    }
} 

একইভাবে "ইসস্যাক্সেস" "সাফল্য" হয়ে যাবে, যদি না "আইসআইসস্যাক্সেস" বা "getIsSuccess" নামকরণ করা হয়

এখানে আরও পড়ুন: http://www.citrine.io/blog/2015/5/20/jackson-json- প্রসেসর


6
জাভা বুলিয়ান ডেটা টাইপের নামকরণ কনভেনশন নয় বৈধ হতে হবে এবং ভালিড (), সেটভালিড ()
ভেলস 4j

4
তবে কি ঠিক তা হওয়ার কথা নয়? একটি সম্মেলন? যদি এটি বিদ্যমান থাকে, আপনি জ্যাকসন রেফারেন্সের সাথে লিঙ্ক করতে পারেন যে বলে যে এটি জেএসওন ক্ষেত্র হিসাবে গেটের নাম ব্যবহার করে? বা আপনি কি এটি একটি খারাপ নকশা পছন্দ বলে মনে করেন?
অভিনব বিশ্বক

4
আমি আশা করি
এটির

@ vels4j আপনি যখন সুনির্দিষ্ট সুনির্দিষ্ট বাস্তবায়ন নিয়ে কাজ করছেন তখন নামকরণের কনভেনশনগুলি উইন্ডোটির বাইরে চলে যায়।
ড্রাগস

13

নীচে উভয় টীকা ব্যবহার করে, আউটপুট জেএসওএনকে অন্তর্ভুক্ত করতে বাধ্য করে is_xxx:

@get:JsonProperty("is_something")
@param:JsonProperty("is_something")

এটি এই প্রশ্নের সেরা উত্তর।
ডাস্টিনেভেন

4
এটা কি জাভা? এটা কি কোটলিন?
3:30

5

আপনি ObjectMapperনিম্নলিখিত হিসাবে আপনার কনফিগার করতে পারেন :

mapper.setPropertyNamingStrategy(new PropertyNamingStrategy() {
            @Override
            public String nameForGetterMethod(MapperConfig<?> config, AnnotatedMethod method, String defaultName)
            {
                if(method.hasReturnType() && (method.getRawReturnType() == Boolean.class || method.getRawReturnType() == boolean.class)
                        && method.getName().startsWith("is")) {
                    return method.getName();
                }
                return super.nameForGetterMethod(config, method, defaultName);
            }
        });

4
আমি পছন্দ করি আপনি এটি কনফিগারেশনের মাধ্যমে সমাধান করার চেষ্টা করছেন। তবে এটি কেবল তখনই কাজ করবে যদি আপনি সর্বদা আপনার বুলিয়ান ক্ষেত্র এবং JSON বৈশিষ্ট্যগুলিকে "হয়" দিয়ে উপস্থাপন করেন। বলুন আপনার কাছে আরও একটি বুলিয়ান ফিল্ড রয়েছে যার নাম "সক্ষমিত" রয়েছে যা আপনি এটির মতো সিরিয়ালাইজ করতে চান। উত্পন্ন পদ্ধতিটি "isnnable ()" হওয়ায়, উপরের কোডটি কেবল "সক্ষম" এর পরিবর্তে এটি "isnnable" এ সিরিয়ালাইজ করবে। শেষ পর্যন্ত, সমস্যাটি হ'ল "এক্স" এবং "ইসএক্সএক্স" উভয় ক্ষেত্রেই, গ্রহপৃষ্ঠটি "ইসএক্স ()" পদ্ধতি উত্পন্ন করে; সুতরাং আপনি ক্ষেত্রের সাথে মিল রেখে কোনও সম্পত্তির নাম নির্ধারণ করতে পারবেন না।
ডেভিড সিগাল

বুড়াক জবাবের ভিত্তিতে ডেভিডসিগাল বেসটি এই জাতীয় মামলার সমর্থন করার জন্য আমি নীচের উত্তরটি প্রসারিত করেছি।
এডমন্ডপি

4

আপনি যখন কোটলিন এবং ডেটা ক্লাস ব্যবহার করছেন:

data class Dto(
    @get:JsonProperty("isSuccess") val isSuccess: Boolean
)

আপনি @param:JsonProperty("isSuccess")যদি জেএসওএনকেও ডিজিটালাইজ করতে চলেছেন তবে আপনাকে যুক্ত করতে হবে।


2

উত্কর্ষের উত্তরের ভিত্তিতে ..

গেটারের নাম বিয়োগ / জেএসএন নাম হিসাবে ব্যবহৃত হয়।

public class Example{
    private String radcliffe; 

    public getHarryPotter(){
        return radcliffe; 
    }
}

{"হ্যারিপোটার" হিসাবে সংরক্ষণ করা হয়েছে : "যাই হোক আপনি গেভইয়ার"}


ডেসারিয়ালাইজেশনের জন্য, জ্যাকসন সেটার এবং মাঠের নাম উভয়ের বিরুদ্ধে পরীক্ষা করে। জসন স্ট্রিং {"word1": "উদাহরণ"} এর জন্য , নীচের উভয়টি বৈধ।

public class Example{
    private String word1; 

    public setword2( String pqr){
        this.word1 = pqr; 
    }
}

public class Example2{
    private String word2; 

    public setWord1(String pqr){
        this.word2 = pqr ; 
    }
}

আরও আকর্ষণীয় প্রশ্ন হ'ল জ্যাকসন কোন আদেশটি ডিসিরিয়ালাইজেশনের জন্য বিবেচনা করে। আমি deserialize চেষ্টা করলে : { "Myname" "WORD1"} সঙ্গে

public class Example3{
    private String word1;
    private String word2; 

    public setWord1( String parameter){
        this.word2 = parameter ; 
    }
}

আমি উপরের কেসটি পরীক্ষা করে দেখিনি, তবে শব্দ 1 এবং শব্দের 2 এর মানগুলি দেখতে আকর্ষণীয় হবে ...

দ্রষ্টব্য: কোন ক্ষেত্রগুলি একই হতে হবে তা জোর দেওয়ার জন্য আমি মারাত্মকভাবে আলাদা আলাদা নাম ব্যবহার করেছি।


1

এই সমস্যার জন্য অন্য একটি পদ্ধতি আছে।

কেবলমাত্র একটি নতুন উপ-শ্রেণীর সংজ্ঞা দেওয়া হবে প্রপার্টিনামিংস্ট্রেটজি প্রসারিত এবং এটি অবজেক্টম্যাপার উদাহরণে পাস করুন।

এখানে একটি কোড স্নিপেট আরও সাহায্য হতে পারে:

mapper.setPropertyNamingStrategy(new PropertyNamingStrategy() {
        @Override
        public String nameForGetterMethod(MapperConfig<?> config, AnnotatedMethod method, String defaultName) {
            String input = defaultName;
            if(method.getName().startsWith("is")){
                input = method.getName();
            }

            //copy from LowerCaseWithUnderscoresStrategy
            if (input == null) return input; // garbage in, garbage out
            int length = input.length();
            StringBuilder result = new StringBuilder(length * 2);
            int resultLength = 0;
            boolean wasPrevTranslated = false;
            for (int i = 0; i < length; i++)
            {
                char c = input.charAt(i);
                if (i > 0 || c != '_') // skip first starting underscore
                {
                    if (Character.isUpperCase(c))
                    {
                        if (!wasPrevTranslated && resultLength > 0 && result.charAt(resultLength - 1) != '_')
                        {
                            result.append('_');
                            resultLength++;
                        }
                        c = Character.toLowerCase(c);
                        wasPrevTranslated = true;
                    }
                    else
                    {
                        wasPrevTranslated = false;
                    }
                    result.append(c);
                    resultLength++;
                }
            }
            return resultLength > 0 ? result.toString() : input;
        }
    });

1

আমি কিছু কাস্টম নামকরণ কৌশল নিয়ে গণ্ডগোল করতে চাইনি বা কিছু অ্যাক্সেসর পুনরায় তৈরি করতে চাই না।
যত কম কোড, ততই আমি সুখী।

এটি আমাদের জন্য কৌশলটি করেছে:

import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import com.fasterxml.jackson.annotation.JsonProperty;

@JsonIgnoreProperties({"success", "deleted"}) // <- Prevents serialization duplicates 
public class MyResponse {

    private String id;
    private @JsonProperty("isSuccess") boolean isSuccess; // <- Forces field name
    private @JsonProperty("isDeleted") boolean isDeleted;

}

1

গৃহীত উত্তরটি আমার মামলার পক্ষে কাজ করবে না।

আমার ক্ষেত্রে, ক্লাসটি আমার নিজস্ব নয়। সমস্যাযুক্ত শ্রেণীটি তৃতীয় পক্ষের নির্ভরতা থেকে আসে, সুতরাং আমি @JsonPropertyএটিতে টীকা যুক্ত করতে পারি না ।

এটি সমাধানের জন্য উপরের @ বুর্ক উত্তর থেকে অনুপ্রাণিত হয়ে আমি নিম্নলিখিত অনুসারে একটি কাস্টম তৈরি করেছি PropertyNamingStrategy:

mapper.setPropertyNamingStrategy(new PropertyNamingStrategy() {
  @Override
  public String nameForSetterMethod(MapperConfig<?> config, AnnotatedMethod method, String defaultName)
  {
    if (method.getParameterCount() == 1 &&
            (method.getRawParameterType(0) == Boolean.class || method.getRawParameterType(0) == boolean.class) &&
            method.getName().startsWith("set")) {

      Class<?> containingClass = method.getDeclaringClass();
      String potentialFieldName = "is" + method.getName().substring(3);

      try {
        containingClass.getDeclaredField(potentialFieldName);
        return potentialFieldName;
      } catch (NoSuchFieldException e) {
        // do nothing and fall through
      }
    }

    return super.nameForSetterMethod(config, method, defaultName);
  }

  @Override
  public String nameForGetterMethod(MapperConfig<?> config, AnnotatedMethod method, String defaultName)
  {
    if(method.hasReturnType() && (method.getRawReturnType() == Boolean.class || method.getRawReturnType() == boolean.class)
        && method.getName().startsWith("is")) {

      Class<?> containingClass = method.getDeclaringClass();
      String potentialFieldName = method.getName();

      try {
        containingClass.getDeclaredField(potentialFieldName);
        return potentialFieldName;
      } catch (NoSuchFieldException e) {
        // do nothing and fall through
      }
    }
    return super.nameForGetterMethod(config, method, defaultName);
  }
});

মূলত এটি যা করে তা হ'ল সিরিয়ালাইজেশন এবং ডিসরিয়ালাইজ করার আগে এটি লক্ষ্য / উত্স শ্রেণীর মধ্যে পরীক্ষা করে যে কোন সম্পত্তির নামটি শ্রেণিতে উপস্থিত রয়েছে, তা সে সম্পত্তি isEnabledবা enabledসম্পত্তি।

তার উপর ভিত্তি করে, ম্যাপারটি বিদ্যমান সম্পত্তি যেটির নামটি সিরিয়ালায়িত করবে এবং deserialize করবে।


0

আপনি আদিম বুলেটিয়ানটি জাভা.লং.বুলিয়ান (+ ব্যবহার @JsonPropery) এ পরিবর্তন করতে পারেন

@JsonProperty("isA")
private Boolean isA = false;

public Boolean getA() {
    return this.isA;
}

public void setA(Boolean a) {
    this.isA = a;
}

আমার জন্য দুর্দান্ত কাজ করেছেন।

আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.