Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    primarykey
    data
    text
    <p>I would like to extend nice answer of Jerome Dalbert. I found very easy to write your own annotation validators in JSR-303 way. You are not limited to have "one field" validation. You can create your own annotation on type level and have complex validation (see examples below). I prefer this way because I don't need mix different types of validation (Spring and JSR-303) like Jerome do. Also this validators are "Spring aware" so you can use @Inject/@Autowire out of box.</p> <p><strong>Example of custom object validation:</strong></p> <pre><code>@Target({ TYPE, ANNOTATION_TYPE }) @Retention(RUNTIME) @Constraint(validatedBy = { YourCustomObjectValidator.class }) public @interface YourCustomObjectValid { String message() default "{YourCustomObjectValid.message}"; Class&lt;?&gt;[] groups() default {}; Class&lt;? extends Payload&gt;[] payload() default {}; } public class YourCustomObjectValidator implements ConstraintValidator&lt;YourCustomObjectValid, YourCustomObject&gt; { @Override public void initialize(YourCustomObjectValid constraintAnnotation) { } @Override public boolean isValid(YourCustomObject value, ConstraintValidatorContext context) { // Validate your complex logic // Mark field with error ConstraintViolationBuilder cvb = context.buildConstraintViolationWithTemplate(context.getDefaultConstraintMessageTemplate()); cvb.addNode(someField).addConstraintViolation(); return true; } } @YourCustomObjectValid public YourCustomObject { } </code></pre> <p><strong>Example of generic fields equality:</strong></p> <pre><code>import static java.lang.annotation.ElementType.ANNOTATION_TYPE; import static java.lang.annotation.ElementType.TYPE; import static java.lang.annotation.RetentionPolicy.RUNTIME; import java.lang.annotation.Documented; import java.lang.annotation.Retention; import java.lang.annotation.Target; import javax.validation.Constraint; import javax.validation.Payload; @Target({ TYPE, ANNOTATION_TYPE }) @Retention(RUNTIME) @Constraint(validatedBy = { FieldsEqualityValidator.class }) public @interface FieldsEquality { String message() default "{FieldsEquality.message}"; Class&lt;?&gt;[] groups() default {}; Class&lt;? extends Payload&gt;[] payload() default {}; /** * Name of the first field that will be compared. * * @return name */ String firstFieldName(); /** * Name of the second field that will be compared. * * @return name */ String secondFieldName(); @Target({ TYPE, ANNOTATION_TYPE }) @Retention(RUNTIME) public @interface List { FieldsEquality[] value(); } } import java.lang.reflect.Field; import javax.validation.ConstraintValidator; import javax.validation.ConstraintValidatorContext; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.util.ReflectionUtils; public class FieldsEqualityValidator implements ConstraintValidator&lt;FieldsEquality, Object&gt; { private static final Logger log = LoggerFactory.getLogger(FieldsEqualityValidator.class); private String firstFieldName; private String secondFieldName; @Override public void initialize(FieldsEquality constraintAnnotation) { firstFieldName = constraintAnnotation.firstFieldName(); secondFieldName = constraintAnnotation.secondFieldName(); } @Override public boolean isValid(Object value, ConstraintValidatorContext context) { if (value == null) return true; try { Class&lt;?&gt; clazz = value.getClass(); Field firstField = ReflectionUtils.findField(clazz, firstFieldName); firstField.setAccessible(true); Object first = firstField.get(value); Field secondField = ReflectionUtils.findField(clazz, secondFieldName); secondField.setAccessible(true); Object second = secondField.get(value); if (first != null &amp;&amp; second != null &amp;&amp; !first.equals(second)) { ConstraintViolationBuilder cvb = context.buildConstraintViolationWithTemplate(context.getDefaultConstraintMessageTemplate()); cvb.addNode(firstFieldName).addConstraintViolation(); ConstraintViolationBuilder cvb = context.buildConstraintViolationWithTemplate(context.getDefaultConstraintMessageTemplate()); cvb.addNode(someField).addConstraintViolation(secondFieldName); return false; } } catch (Exception e) { log.error("Cannot validate fileds equality in '" + value + "'!", e); return false; } return true; } } @FieldsEquality(firstFieldName = "password", secondFieldName = "confirmPassword") public class NewUserForm { private String password; private String confirmPassword; } </code></pre>
    singulars
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. VO
      singulars
      1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload