দুই বা ততোধিক ক্ষেত্রের সংমিশ্রণে আমি কীভাবে বৈধতা দিতে পারি?


92

আমি আমার মডেলগুলি যাচাই করতে JPA 2.0 / হাইবারনেট বৈধতা ব্যবহার করছি using আমার এখন এমন পরিস্থিতি রয়েছে যেখানে দুটি ক্ষেত্রের সংমিশ্রণটি বৈধ করতে হবে:

public class MyModel {
    public Integer getValue1() {
        //...
    }
    public String getValue2() {
        //...
    }
}

মডেল অবৈধ উভয় getValue1()এবং getValue2()হয় nullএবং বৈধ অন্যথায়।

আমি জেপিএ ২.০ / হাইবারনেটের সাথে এই জাতীয় বৈধতা কীভাবে সম্পাদন করতে পারি? একটি সাধারণ @NotNullটীকা সহ উভয় প্রযোজক অবশ্যই বৈধতা পাস করার জন্য অকার্যকর হতে হবে।


উত্তর:


102

একাধিক বৈশিষ্ট্য বৈধতার জন্য আপনার শ্রেণি-স্তরের সীমাবদ্ধতাগুলি ব্যবহার করা উচিত। থেকে সিম ভ্যালিডেশন স্নিক পিক পার্ট II: কাস্টম সীমাবদ্ধতার :

### শ্রেণী-স্তরের প্রতিবন্ধকতা

আপনারা কেউ কেউ একাধিক সম্পত্তি বিস্তৃত বাধা প্রয়োগ করার ক্ষমতা বা বিভিন্ন বৈশিষ্ট্যের উপর নির্ভরশীল প্রতিবন্ধকতা প্রকাশ করার ক্ষমতা নিয়ে উদ্বেগ প্রকাশ করেছেন। শাস্ত্রীয় উদাহরণ হ'ল ঠিকানা বৈধতা। ঠিকানাগুলির জটিল বিধি রয়েছে:

  • রাস্তার নাম কিছুটা প্রমিত এবং অবশ্যই এটির দৈর্ঘ্যের সীমা থাকতে হবে
  • জিপ কোড কাঠামো পুরোপুরি দেশের উপর নির্ভর করে
  • শহরটি প্রায়শই একটি পিনকোডের সাথে সম্পর্কিত হতে পারে এবং কিছু ত্রুটি পরীক্ষা করা যায় (শর্ত থাকে যে কোনও বৈধতা পরিষেবা অ্যাক্সেসযোগ্য)
  • এই আন্তঃনির্ভরতার কারণে বিলটি মাপসই করার জন্য একটি সাধারণ সম্পত্তি স্তরের বাধা

বিনের বৈধকরণের স্পেসিফিকেশন দ্বারা প্রদত্ত সমাধানটি দ্বিগুণ:

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

শ্রেণি স্তরের সীমাবদ্ধতা হ'ল নিয়মিত প্রতিবন্ধকতা (টিকা / বাস্তবায়ন যুগল) যা কোনও সম্পত্তির পরিবর্তে কোনও শ্রেণিতে প্রয়োগ হয়। অন্যভাবে বলেছে, শ্রেণি-স্তরের সীমাবদ্ধতাগুলি বস্তুর উদাহরণ (সম্পত্তি মানের চেয়ে) প্রাপ্ত করে isValid

@AddressAnnotation 
public class Address {
    @NotNull @Max(50) private String street1;
    @Max(50) private String street2;
    @Max(10) @NotNull private String zipCode;
    @Max(20) @NotNull String city;
    @NotNull private Country country;
    
    ...
}

@Constraint(validatedBy = MultiCountryAddressValidator.class)
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
public @interface AddressAnnotation {
    String message() default "{error.address}";
    Class<?>[] groups() default { };
    Class<? extends Payload>[] payload() default { };
}

public class MultiCountryAddressValidator implements ConstraintValidator<AddressAnnotation, Address> {
    public void initialize(AddressAnnotation constraintAnnotation) {
    // initialize the zipcode/city/country correlation service
    }

    /**
     * Validate zipcode and city depending on the country
     */
    public boolean isValid(Address object, ConstraintValidatorContext context) {
        if (!(object instanceof Address)) {
            throw new IllegalArgumentException("@Address only applies to Address");
        }
        Address address = (Address) object;
        Country country = address.getCountry();
        if (country.getISO2() == "FR") {
            // check address.getZipCode() structure for France (5 numbers)
            // check zipcode and city correlation (calling an external service?)
            return isValid;
        } else if (country.getISO2() == "GR") {
            // check address.getZipCode() structure for Greece
            // no zipcode / city correlation available at the moment
            return isValid;
        }
        // ...
    }
}

উন্নত ঠিকানা বৈধকরণের নিয়মগুলি অ্যাড্রেস অবজেক্টের বাইরে রেখে প্রয়োগ করা হয়েছে MultiCountryAddressValidator। অবজেক্ট দৃষ্টান্ত অ্যাক্সেসের মাধ্যমে, শ্রেণি স্তরের সীমাবদ্ধতার অনেকটা নমনীয়তা থাকে এবং একাধিক সম্পর্কিত সম্পর্কযুক্ত বৈশিষ্ট্যকে বৈধতা দিতে পারে। নোট করুন যে এখানে অর্ডারটি সমীকরণের বাইরে রেখে গেছে, আমরা পরবর্তী পোস্টে এটিতে ফিরে আসব।

বিশেষজ্ঞ গ্রুপ বিভিন্ন একাধিক সম্পত্তি সমর্থন পদ্ধতির বিষয়ে আলোচনা করেছে: আমরা মনে করি শ্রেণিবদ্ধ স্তরের সীমাবদ্ধতা নির্ভরতা জড়িত অন্যান্য সম্পত্তি স্তরের পদ্ধতির তুলনায় পর্যাপ্ত সরলতা এবং নমনীয়তা উভয়ই সরবরাহ করে। আপনার মতামত স্বাগত।


17
ইন্টারফেস কনস্ট্রেন্টভালিডেটর এবং টীকা @ কনস্ট্রেন্টের উদাহরণটিতে উল্টানো হয়েছে। এবং বৈধ () 2 পরামিতি নেয় takes
গিলাইম হুস্টা

4
TYPEএবং যথাক্রমে এবং এর RUNTIMEসাথে প্রতিস্থাপন করা উচিত । ElementType.TYPERetentionPolicy.RUNTIME
চিহ্ন.মন্টেইরো

4
@ চিহ্নিত.monteiro আপনি স্থিতিশীল আমদানি ব্যবহার করতে পারেন: import static java.lang.annotation.ElementType.*;এবংimport static java.lang.annotation.RetentionPolicy.*;
ক্যাসিওমোলিন

4
বিনের বৈধকরণের সাথে কাজ করার জন্য আমি উদাহরণটি আবার লিখেছি। এখানে দেখুন ।
ক্যাসিওমোলিন

4
টীকাগুলির প্যারামিটারগুলি নির্দিষ্টকরণের মধ্যে সঠিক নয়, কারণ এই উত্তরটির অধীনে ক্যাসিও দ্বারা একটি বার্তা, গোষ্ঠী এবং পে-লোডের মতো উল্লেখ থাকতে হয়েছিল।
পিটার এস 13

38

বিনের বৈধকরণের সাথে সঠিকভাবে কাজ করতে , পাস্কাল থিভেন্টের উত্তরে প্রদত্ত উদাহরণটি নিম্নরূপ লিখিত হতে পারে:

@ValidAddress
public class Address {

    @NotNull
    @Size(max = 50)
    private String street1;

    @Size(max = 50)
    private String street2;

    @NotNull
    @Size(max = 10)
    private String zipCode;

    @NotNull
    @Size(max = 20)
    private String city;

    @Valid
    @NotNull
    private Country country;

    // Getters and setters
}
public class Country {

    @NotNull
    @Size(min = 2, max = 2)
    private String iso2;

    // Getters and setters
}
@Documented
@Target(TYPE)
@Retention(RUNTIME)
@Constraint(validatedBy = { MultiCountryAddressValidator.class })
public @interface ValidAddress {

    String message() default "{com.example.validation.ValidAddress.message}";

    Class<?>[] groups() default {};

    Class<? extends Payload>[] payload() default {};
}
public class MultiCountryAddressValidator 
       implements ConstraintValidator<ValidAddress, Address> {

    public void initialize(ValidAddress constraintAnnotation) {

    }

    @Override
    public boolean isValid(Address address, 
                           ConstraintValidatorContext constraintValidatorContext) {

        Country country = address.getCountry();
        if (country == null || country.getIso2() == null || address.getZipCode() == null) {
            return true;
        }

        switch (country.getIso2()) {
            case "FR":
                return // Check if address.getZipCode() is valid for France
            case "GR":
                return // Check if address.getZipCode() is valid for Greece
            default:
                return true;
        }
    }
}

কোনও সিডিআই বিনের জন্য ওয়েবস্পিয়ারের বিশ্রামের প্রকল্পে কীভাবে বুটস্ট্র্যাপ বা কাস্টম বৈধকরণকারীর কাছে প্রার্থনা করবেন? আমি সমস্ত লিখেছি কিন্তু কাস্টম সীমাবদ্ধতা কাজ করছে না বা প্রার্থনা করছে না
বালাজিচন্দ্র

আমি অনুরূপ বৈধতার সাথে আটকে আছি তবে আমার isoA2Codeডিবি Countryটেবিলে সঞ্চিত আছে । এখান থেকে কোনও ডিবি কল করা কি ভাল ধারণা? এছাড়াও, আমি তাদের বৈধতার পরে লিঙ্ক করতে চাই কারণ Address belongs_toএকটি Countryএবং আমি টেবিলের বিদেশী কীটি addressপ্রবেশ করতে চাই country। আমি কীভাবে দেশকে সম্বোধনের সাথে সংযুক্ত করব?
ক্রোজাইন

মনে রাখবেন যে আপনি যখন কোনও ভুল অবজেক্টে কোনও প্রকারের বৈধতা টীকা নির্ধারণ করবেন, তখন ব্যন বিন বৈধকরণ কাঠামো দ্বারা ব্যতিক্রম হবে। উদাহরণস্বরূপ, যদি আপনি @ValidAddressদেশটির অবজেক্টে টিকাটি সেট করেন , আপনি No validator could be found for constraint 'com.example.validation.ValidAddress' validating type 'com.example.Country'ব্যতিক্রম পাবেন।
জ্যাকব ভ্যান লিনজেন

12

কাস্টম বর্গ স্তর যাচাইকারী, যেতে উপায় যখন আপনি সিম ভ্যালিডেশন স্পেসিফিকেশনের সঙ্গে থাকার উদাহরণ চান এখানে

আপনি যদি হাইবারনেট ভ্যালিডেটর বৈশিষ্ট্যটি ব্যবহার করে সন্তুষ্ট হন তবে আপনি @ স্ক্রিপ্টএসর্ট ব্যবহার করতে পারেন , যা ভ্যালিডেটর ৪৪.১.০ থেকে সরবরাহ করা হয়েছে।ফাইনাল । এর জাভাডক থেকে ব্যতীত:

স্ক্রিপ্ট এক্সপ্রেশন যেকোন স্ক্রিপ্টিং বা এক্সপ্রেশন ভাষায় লেখা যেতে পারে, যার জন্য একটি জেএসআর 223 ("জাভাটিএম প্ল্যাটফর্মের জন্য স্ক্রিপ্টিং") সামঞ্জস্যপূর্ণ ইঞ্জিনটি ক্লাসপথে পাওয়া যাবে।

উদাহরণ:

@ScriptAssert(lang = "javascript", script = "_this.value1 != null || _this != value2)")
public class MyBean {
  private String value1;
  private String value2;
}

হ্যাঁ, এবং জাভা 6 এর মধ্যে রাইনো (জাভাস্ক্রিপ্ট ইঞ্জিন) অন্তর্ভুক্ত রয়েছে যাতে আপনি অতিরিক্ত নির্ভরতা যুক্ত না করেই জাভাস্ক্রিপ্টটিকে এক্সপ্রেশন ভাষা হিসাবে ব্যবহার করতে পারেন।

4
হাইবারনেট ভ্যালিডেটর 5.1.1 এর সাথে কীভাবে এরকম একটি বৈধতা তৈরি করা যায় তার একটি উদাহরণ এখানে রয়েছে inal ফাইনাল
ইভান
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.