zoukankan      html  css  js  c++  java
  • Spring MVC 使用介绍(十六)数据验证 (三)分组、自定义、跨参数、其他

    一、概述

    除了依赖注入、方法参数,Bean Validation 1.1定义的功能还包括:

    1、分组验证

    2、自定义验证规则

    3、类级别验证

    4、跨参数验证

    5、组合多个验证注解

    6、其他

    二、分组验证

    通过分组,可实现不同情况下的不同验证规则,示例如下:

    1、定义分组接口

    public interface AddView { 
    }
    public interface UpdateView {
    }

    2、定义实体

    public class Person {
        @Null(groups = AddView.class)
        @NotNull(groups = {UpdateView.class, Default.class})
        private Integer id;
        ...
    }

      注:不指定分组,即为Default分组

    3、业务类

    @Service
    @Validated
    public class PersonService {
        @Validated(AddView.class)
        public void addPerson(@Valid Person person) {}
        
        @Validated({UpdateView.class})
        public void updatePerson(@Valid Person person) {}
        
        public void defaultOp(@Valid Person person) {}
    }

    4、测试

    @RunWith(SpringJUnit4ClassRunner.class)
    @ContextConfiguration(locations = "classpath:spring-context.xml")
    public class ValidTest {
        @Autowired
        private PersonService testService;
    
        @Test(expected = ConstraintViolationException.class)
        public void test1() {
            Person person = new Person();
            person.setId(12);
            testService.addPerson(person);
        }
        
        @Test(expected = ConstraintViolationException.class)
        public void test2() {
            Person person = new Person();
            testService.updatePerson(person);
        }
        
        @Test(expected = ConstraintViolationException.class)
        public void test3() {
            Person person = new Person();
            testService.defaultOp(person);
        }
    }

    三、自定义验证规则

    系统预定义的验证注解不能满足需求时,可自定义验证注解,示例如下:

    1、自定义注解

    @Target({ FIELD, METHOD, PARAMETER, ANNOTATION_TYPE })
    @Retention(RUNTIME)
    @Constraint(validatedBy = ForbiddenValidator.class)
    @Documented
    public @interface Forbidden {
        //默认错误消息
        String message() default "{forbidden.word}";
    
        //分组
        Class<?>[] groups() default { };
    
        //负载
        Class<? extends Payload>[] payload() default { };
    
        //指定多个时使用
        @Target({ FIELD, METHOD, PARAMETER, ANNOTATION_TYPE })
        @Retention(RUNTIME)
        @Documented
        @interface List {
            Forbidden[] value();
        }
    }

    2、自定义注解处理类

    public class ForbiddenValidator implements ConstraintValidator<Forbidden, String> {
        private String[] forbiddenWords = {"admin"};
    
        @Override
        public void initialize(Forbidden constraintAnnotation) {
            //初始化,得到注解数据
        }
    
        @Override
        public boolean isValid(String value, ConstraintValidatorContext context) {
            if(StringUtils.isEmpty(value)) {
                return true;
            }
    
            for(String word : forbiddenWords) {
                if(value.contains(word)) {
                    return false;//验证失败
                }
            }
            return true;
        }
    }

    3、默认错误消息

    # format.properties
    forbidden.word=包含敏感词汇

    4、实体类

    public class Person {
      @Forbidden
      private String name;
      ...
    }

    5、业务类

    @Service
    @Validated
    public class PersonService {
        public void defaultOp(@Valid Person person) {
            
        }
    }

    6、测试

    @Test(expected = ConstraintViolationException.class)
    public void test4() {
        Person person = new Person();
        person.setName("admin");
        testService.defaultOp(person);
    }

    四、类级别验证

    定义类级别验证,可实现对象中的多个属性组合验证,示例如下:

    1、定义注解

    @Target({ TYPE, ANNOTATION_TYPE})
    @Retention(RUNTIME)
    @Documented
    @Constraint(validatedBy = CheckPasswordValidator.class)
    public @interface CheckPassword {
        //默认错误消息
        String message() default "";
    
        //分组
        Class<?>[] groups() default { };
    
        //负载
        Class<? extends Payload>[] payload() default { };
    
        //指定多个时使用
        @Target({ FIELD, METHOD, PARAMETER, ANNOTATION_TYPE })
        @Retention(RUNTIME)
        @Documented
        @interface List {
            CheckPassword[] value();
        }
    }

    2、定义处理类

    public class CheckPasswordValidator implements ConstraintValidator<CheckPassword, Person> {
        @Override
        public void initialize(CheckPassword constraintAnnotation) {
        }
    
        @Override
        public boolean isValid(Person person, ConstraintValidatorContext context) {
            if(person == null) {
                return true;
            }
    
            //没有填密码
            if(!StringUtils.isEmpty(person.getNewPassword())) {
                context.disableDefaultConstraintViolation();
                context.buildConstraintViolationWithTemplate("{password.null}")
                        .addPropertyNode("password")
                        .addConstraintViolation();
                return false;
            }
    
            if(!StringUtils.isEmpty(person.getConfirmPassword())) {
                context.disableDefaultConstraintViolation();
                context.buildConstraintViolationWithTemplate("{password.confirmation.null}")
                        .addPropertyNode("confirmation")
                        .addConstraintViolation();
                return false;
            }
    
            //两次密码不一样
            if (!person.getNewPassword().equals(person.getConfirmPassword())) {
                context.disableDefaultConstraintViolation();
                context.buildConstraintViolationWithTemplate("{password.confirmation.error}")
                        .addPropertyNode("confirmation")
                        .addConstraintViolation();
                return false;
            }
            return true;
        }
    }

    3、实体

    @CheckPassword
    public class Person {
        private String newPassword;
        private String confirmPassword;
        ...
    }

    4、业务类

    @Service
    @Validated
    public class PersonService {
        public void checkClassValidation(@Valid Person person) {
            
        }
    }

    5、测试

    @Test(expected = ConstraintViolationException.class)
    public void test4() {
        Person person = new Person();
        person.setNewPassword("asd");
        person.setConfirmPassword("12132");
        testService.checkClassValidation(person);
    }

    五、跨参数验证

    使用跨参数验证,可实现方法级别中的多个参数组合验证,示例如下:

    1、定义注解

    @Constraint(validatedBy = CrossParameterValidator.class)
    @Target({ METHOD, CONSTRUCTOR, ANNOTATION_TYPE })
    @Retention(RUNTIME)
    @Documented
    public @interface CrossParameter {
        String message() default "{password.confirmation.error}";
        Class<?>[] groups() default { };
        Class<? extends Payload>[] payload() default { };
    }

    2、定义处理类

    @SupportedValidationTarget(ValidationTarget.PARAMETERS)
    public class CrossParameterValidator implements ConstraintValidator<CrossParameter, Object[]> {
        @Override
        public void initialize(CrossParameter constraintAnnotation) {
        }
    
        @Override
        public boolean isValid(Object[] value, ConstraintValidatorContext context) {
            if(value == null || value.length != 2) {
                throw new IllegalArgumentException("must have two args");
            }
            if(value[0] == null || value[1] == null) {
                return true;
            }
            if(value[0].equals(value[1])) {
                return true;
            }
            return false;
        }
    }

    3、业务类

    @Service
    @Validated
    public class PersonService {
        @CrossParameter
        public void checkParaValidation(String pw1, String pw2) {
            
        }
    }

    4、测试

    @Test(expected = ConstraintViolationException.class)
    public void test5() {
        testService.checkParaValidation("asd", "123");
    }

    六、组合多个验证注解

    可将多个注解组合成一个注解,示例如下:

    1、定义注解

    @Target({ FIELD})
    @Retention(RUNTIME)
    @Documented
    @NotNull
    @Min(1)
    @Constraint(validatedBy = { })
    public @interface NotNullMin {
        String message() default "";
        Class<?>[] groups() default { };
        Class<? extends Payload>[] payload() default { };
    }

    2、实体

    public class Person {
        @NotNullMin
        private Integer id;
        ...
    }

    3、业务类

    @Service
    @Validated
    public class PersonService {
        public void checkCompositionValidation(@Valid Person person) {
            
        }
    }

    4、测试

    @Test(expected = ConstraintViolationException.class)
    public void test6() {
        Person person = new Person();
        testService.checkCompositionValidation(person);
    }

    七、其他

    Bean Validation 1.1还支持本地化、脚本验证器,详细见参考文档

    参考:

    Spring4新特性——集成Bean Validation 1.1(JSR-349)到SpringMVC

  • 相关阅读:
    团队作业2
    团队作业2
    软件工程-团队作业1
    软件工程第一次作业
    自我介绍
    软件工程第一次作业
    Python3中采用PyInstaller打包工程项目
    mol2分子库文件拆分成单个mol2文件
    化学信息包安装
    单词读音音频源网址
  • 原文地址:https://www.cnblogs.com/MattCheng/p/10697644.html
Copyright © 2011-2022 走看看