How to create a constraint validator for multiple fields through annotation in spring 4.*

匿名 (未验证) 提交于 2019-12-03 01:03:01

问题:

How to create a validator restrictions for more fields through annotation in spring 4.* for example

@UniqueValidator

@Entity @Table(name = "persons") @UniqueValidator(message="Peson already exist",columns={"name","lastName"}) public class {     @Column     private String name;     @Column     private String lastName; } 

roughly speaking..

select ... from persons where name='qwerty' and lastName='asdfgh' 

回答1:

Here's one way to do it in Spring MVC and JSR 303 validation:

Create a constraint annotation:

package com.awgtek.model.validation;  import java.lang.annotation.Documented; import java.lang.annotation.ElementType; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target;  import javax.validation.Constraint; import javax.validation.Payload;  /**  * The target field should be unique in the data store.  */ @Documented @Constraint(validatedBy = UniqueNameValidator.class) @Target(ElementType.TYPE) @Retention(RetentionPolicy.RUNTIME) public @interface UniqueName {      /**      * @return the error message template      */     String message() default "{com.awgtek.model.validation.UniqueName.message}";      /**      * @return the groups the constraint belongs to      */     Class<?>[] groups() default {};      /**      * @return the payload associated to the constraint      */     Class<? extends Payload>[] payload() default {};      /**      * @return a class an instance of which will be used to check the existence of a name.      */     Class<? extends NameExistenceChecker> nameExistenceChecker(); } 

Apply this annotation at the class level to the model class:

package com.awgtek.model;  import com.awgtek.model.validation.MyNameExistenceChecker; import com.awgtek.model.validation.UniqueName; import com.awgtek.model.validation.UniqueNameConstraint;  @UniqueName(groups = UniqueNameConstraint.class,  nameExistenceChecker = MyNameExistenceChecker.class) public class ConfigurationAttribute {      private String name;      private String lastName;      // getters and setters omitted   } 

The UniqueNameValidator:

package com.awgtek.model.validation;  import com.awgtek.service.MyService;  import javax.inject.Inject; import javax.validation.ConstraintValidator; import javax.validation.ConstraintValidatorContext;  public class UniqueNameValidator implements ConstraintValidator<UniqueName, Object> {      @Inject     private NameExistenceCheckerFactory nameExistenceCheckerFactory;      private NameExistenceChecker nameExistenceChecker;      @Override     public void initialize(UniqueName constraintAnnotation) {         nameExistenceChecker = nameExistenceCheckerFactory.get(constraintAnnotation.nameExistenceChecker());     }      @Override     public boolean isValid(Object value, ConstraintValidatorContext context) {         return !nameExistenceChecker.nameExists(value);     } } 

The UniqueNameValidator then depends on a couple of classes:

package com.awgtek.model.validation;  import javax.inject.Inject;  import org.springframework.stereotype.Component;  @Component public class NameExistenceCheckerFactory {      @Inject     private NamespaceNameExistenceChecker namespaceNameExistenceChecker;      @Inject     private MyNameExistenceChecker myNameExistenceChecker;      public NameExistenceChecker get(Class<? extends NameExistenceChecker> clazz) {         if (clazz.equals(MyNameExistenceChecker.class)) {             return myNameExistenceChecker;         }         throw new IllegalStateException("Unknown NameExistenceChecker");     } }  package com.awgtek.model.validation;  public interface NameExistenceChecker {      boolean nameExists(Object objectWithName); } 

The implementation class that actually looks up whether the item exists in the database (via a service):

package com.awgtek.model.validation;  import com.awgtek.model.MyModelClass; import com.awgtek.service.MyService;  import javax.inject.Inject;  import org.springframework.stereotype.Component;  @Component public class AttributeNameExistenceChecker implements NameExistenceChecker {      @Inject     private MyService myService;      @Override     public boolean nameExists(Object objectWithName) {         MyModelClass myObject = (MyModelClass) objectWithName;         return myService.itemAlreadyExists(myObject.getName(), myObject.getLastName());     } } 


标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!