java - Validating collection using Bean Validation is not returning invalid elements properly -


i trying create bv constraint validator collections following example in answer of this link.

public class constraintvalidatorfactoryimpl implements constraintvalidatorfactory {      private validatorcontext validatorcontext;      public constraintvalidatorfactoryimpl(validatorcontext nativevalidator) {         this.validatorcontext = nativevalidator;     }      public <t extends constraintvalidator<?, ?>> t getinstance(class<t> key) {         t instance = null;         try {             instance = key.newinstance();         } catch (exception e) {             e.printstacktrace();         }          if(validatorcontextawareconstraintvalidator.class.isassignablefrom(key)) {             validatorcontextawareconstraintvalidator validator = (validatorcontextawareconstraintvalidator) instance;             validator.setvalidatorcontext(validatorcontext);         }          return instance;     } } 

here validator.

public class cincodevalidator implements constraintvalidator<cincode, string> {      private static pattern cincodepattern;      public void initialize(cincode constraintannotation) {         if (cincodepattern == null) {             cincodepattern = pattern.compile("([0-9]{1,5})");         }     }      public boolean isvalid(string value, constraintvalidatorcontext context) {         boolean result = false;         if (isnotnull(value)) {             result = matchcode(value);         }         if(!result) {             context.disabledefaultconstraintviolation();             context.buildconstraintviolationwithtemplate( "invalid cin code"  ).addconstraintviolation();         }         return result;     }      private static boolean isnotnull(object obj) {         return obj != null;     }      private boolean matchcode(string value) {         matcher matcher = cincodepattern.matcher(value);         return matcher.matches();     } }   public class collectionelementbean {     private string cincode;      @cincode(message = "this should valid cin code")     public string getcincode() {         return cincode;     }      public void setcincode(string cincode) {         this.cincode = cincode;     } }   public interface validatorcontextawareconstraintvalidator {     void setvalidatorcontext(validatorcontext validatorcontext); } 

validator collection:

public class validcollectionvalidator implements constraintvalidator<validcollection, collection>, validatorcontextawareconstraintvalidator {      private static final logger logger = loggerfactory.getlogger(validcollectionvalidator.class);      private validatorcontext validatorcontext;      private class<?> elementtype;     private class<?>[] constraints;     private boolean allviolationmessages;      public void setvalidatorcontext(validatorcontext validatorcontext) {         this.validatorcontext = validatorcontext;     }      public void initialize(validcollection constraintannotation) {         elementtype = constraintannotation.elementtype();         constraints = constraintannotation.constraints();         allviolationmessages = constraintannotation.allviolationmessages();     }      public boolean isvalid(collection collection, constraintvalidatorcontext context) {         boolean valid = true;         if (collection == null) {             return false;         }          validator validator = validatorcontext.getvalidator();         boolean beanconstrained = validator.getconstraintsforclass(elementtype).isbeanconstrained();         (object element : collection) {             set<constraintviolation<?>> violations = new hashset<constraintviolation<?>>();              if (beanconstrained) {                 boolean hasvalidcollectionconstraint = hasvalidcollectionconstraint(elementtype);                 if (hasvalidcollectionconstraint) {                     // elementtype has @validcollection constraint                     violations.addall(validator.validate(element));                 } else {                     violations.addall(validator.validate(element));                 }             } else {                 (class<?> constraint : constraints) {                     string propertyname = constraint.getsimplename();                     propertyname = introspector.decapitalize(propertyname);                     violations.addall(validator.validatevalue(collectionelementbean.class, propertyname, element));  // here, failed values added.                 }             }              if (!violations.isempty()) {                 valid = false;             }              if (allviolationmessages) {                 (constraintviolation<?> violation : violations) {                     logger.debug(violation.getmessage());                     constraintviolationbuilder violationbuilder = context.buildconstraintviolationwithtemplate(violation.getmessage());                     violationbuilder.addconstraintviolation();                 }             }         }         return valid;     }      private boolean hasvalidcollectionconstraint(class<?> beantype) {         beandescriptor beandescriptor = validatorcontext.getvalidator().getconstraintsforclass(beantype);         boolean isbeanconstrained = beandescriptor.isbeanconstrained();         if (!isbeanconstrained) {             return false;         }         set<constraintdescriptor<?>> constraintdescriptors = beandescriptor.getconstraintdescriptors();         (constraintdescriptor<?> constraintdescriptor : constraintdescriptors) {             if (constraintdescriptor.getannotation().annotationtype().getname().equals(validcollection.class.getname())) {                 return true;             }         }         set<propertydescriptor> propertydescriptors = beandescriptor.getconstrainedproperties();         (propertydescriptor propertydescriptor : propertydescriptors) {             constraintdescriptors = propertydescriptor.getconstraintdescriptors();             (constraintdescriptor<?> constraintdescriptor : constraintdescriptors) {                 if (constraintdescriptor.getannotation().annotationtype().getname().equals(validcollection.class.getname())) {                     return true;                 }             }         }         return false;     }  } 

form list of geo id, state number , cin:

public class formwithcollection {     private list<string> cincodes;     @notnull     @validcollection(elementtype = string.class, constraints = { cincode.class })     public list<string> getcincodes() {         return cincodes;     }     public void setcincodes(list<string> cincodes) {         this.cincodes = cincodes;     }     //same goes geo id , state number      } 

test program:

public class validcollectiontest {     private validatorfactory validatorfactory;      @before     public void createvalidatorfactory() {         validatorfactory = validation.builddefaultvalidatorfactory();     }      private validator getvalidator() {         validatorcontext validatorcontext = validatorfactory.usingcontext();         validatorcontext.constraintvalidatorfactory(new constraintvalidatorfactoryimpl(validatorcontext));         validator validator = validatorcontext.getvalidator();         return validator;     }      /**     valid cin code 1 5 digit numeric.     */     @test         public void validatecollectionwithinvalidcin() {         formwithcollection formwithcollection = new formwithcollection();         formwithcollection.setcincode(arrays.aslist("12345", "111a1"));         validator validator = getvalidator();          set<constraintviolation<formwithcollection>> violations = validator.validate(formwithcollection, default.class);         (constraintviolation<formwithcollection> violation : violations) {             system.out.println(violation.getmessage() + "\t" + violation.getinvalidvalue());         }         assert.assertequals(1, violations.size());  // expect see 1 violation there 1 invalid value "111a1". 2 violations returned.     } } 

in validcollectiontest.java , set of constraintviolation iterated list out violations. tried list each violation.getinvalidvalue() let user know. getinvalidvalue() returns whole collection instead of failed value alone.

i'd show user invalid values, because have form this:

+-----------+----------+---------+ |geo id     |state #   |cin      | +-----------+----------+---------+ |           |          |         | +-----------+----------+---------+ |           |          |         | +-----------+----------+---------+ |           |          |         | +-----------+----------+---------+ 

where geo id, state number , cin 3 different input formats.

is there workaround problem enlist failed values ?

i don't think solution in post referring idea. need validation 1 particular constraint? if create constraintvalidator<myconstraint, collection>. iterate passed collection , validate each element yourself. show code have (constraints, constraint validator, etc). or in case using java 8, try latest hibernate validator 5.2 version allows use type annotations, eg list<@myconstraint string>.


Comments

Popular posts from this blog

c++ - No viable overloaded operator for references a map -

java - Custom OutputStreamAppender not run: LOGBACK: No context given for <MYAPPENDER> -

java - Cannot secure connection using TLS -