zoukankan      html  css  js  c++  java
  • springboot(11)使用SpringBoot validator进行数据验证

    简介:

      数据验证是作为一个企业级项目架构上设计的最基础的模块,前辈们曾说过:界面上传递到后台的数据没有百分之百值得相信的!为什么这么说呢?往往我们在编写程序的时候都会感觉后台的验证无关紧要,这样就会给别人空子钻。我可以模拟前台发送的请求到后台地址,那么我如果发送一些涉及系统安全的代码到后台,后果一发不可收拾。接下来我们就来讲解下SpringBoot项目内如何对参数进行校验!

    本章目标

    在SpringBoot项目内完成参数后台数据校验。

    SpringBoot的Web组件内部集成了hibernate-validator,所以我们这里并不需要额外的为验证再导入其他的包,接下来我们先来看看SpringBoot为我们提供了哪些验证。

    一、项目构建

      使用IntelliJ IDEA工具来构建一个SpringBoot项目,预先导入Web依赖

    二、使用验证,书写实体类

      我们接下来创建一个实体叫做DemoEntity,实体内添加几个测试字段并对每个字段都做出验证处理

    public class DemoEntity implements Serializable
    {
        @NotBlank
        @Length(min = 2,max = 10)
        private String name;
    
        @Min(value = 1)
        private int age;
    
        @NotBlank
        @Email
        private String mail;
        
        //自定义验证,值为1或2或3,其他均不可通过验证
        @FlagValidator(values = "1,2,3")
        private String flag;
    
        public String getName() {
            return name;
        }
    
        public void setName(String name) {
            this.name = name;
        }
    
        public int getAge() {
            return age;
        }
    
        public void setAge(int age) {
            this.age = age;
        }
    
        public String getMail() {
            return mail;
        }
    
        public void setMail(String mail) {
            this.mail = mail;
        }
    
        public String getFlag() {
            return flag;
        }
    
        public void setFlag(String flag) {
            this.flag = flag;
        }
    }
    View Code

    三、创建一个名叫IndexController的控制器并通过页面传递参数的形式来校验数据

      我在控制器中注入了一个MessageSource的接口对象,这个对象是用于格式化错误消息的。根据传入的错误字段对象(FieldError)结合hibernate-validator验证的内置错误消息文件进行输出错误消息,hibernate-validator的错误消息支持国际化,所以我们获取错误消息的时候需要传入Locale对象获取本地的国际化类型。hibernate-validator错误消息文件在对应源码包内可以找到
    @RestController
    public class IndexController
    {
    
        @Autowired
        private MessageSource messageSource;
    
        @RequestMapping(value = "/validator",method = RequestMethod.GET)
        public String validator(@Valid DemoEntity entity, BindingResult result) {
            if(result.hasErrors()) {
                StringBuffer msg = new StringBuffer();
                //获取错误字段集合
                List<FieldError> fieldErrors = result.getFieldErrors();
                //获取本地locale,zh_CN
                Locale currentLocale = LocaleContextHolder.getLocale();
                //遍历错误字段获取错误消息
                for (FieldError fieldError :
                        fieldErrors) {
                    //获取错误信息
                    String errorMessage = messageSource.getMessage(fieldError,currentLocale);
                    //添加到错误消息集合内
                    msg.append(fieldError.getField()+":"+errorMessage+" , ");
                }
                return msg.toString();
            }
            return "验证通过," + "	名称:" + entity.getName()+ "	年龄:" + entity.getAge() + "	邮箱地址:"+entity.getMail();
        }
    }

    四、运行测试

    五、自定义验证

    1、自定义验证注解

    我们先来创建一个注解,注解内部需要对应验证注解的验证实现类

    @Documented
    @Retention(RetentionPolicy.RUNTIME)
    @Target({ElementType.PARAMETER, ElementType.FIELD})
    @Constraint(validatedBy = FlagValidatorClass.class)
    public @interface FlagValidator
    {
        //flag的有效值多个使用','隔开
        String values();
        //提示内容
        String message() default "flag不存在";
    
        Class<?>[] groups() default {};
    
        Class<? extends Payload>[] payload() default {};
    }

     2、@Constraint注解,里面传入了一个validatedBy的字段,这个就是我们自定义注解的实现类的类型,实现类代码

      自定义验证实现类里面有两个方法,分别是初始化验证消息、执行验证。

      初始化验证消息方法内你可以得到配置的注解内容,而验证方法则是你的验证业务逻辑。

    public class FlagValidatorClass implements ConstraintValidator<FlagValidator, Object> {
    
        //临时变量保存flag值列表
        private String values;
    
        //初始化values的值
        @Override
        public void initialize(FlagValidator flagValidator) {
            //将注解内配置的值赋值给临时变量
            this.values = flagValidator.values();
        }
    
        //实现验证
        @Override
        public boolean isValid(Object value, ConstraintValidatorContext constraintValidatorContext)
        {
            //分割定义的有效值
            String[] value_array = values.split(",");
            boolean isFlag = false;
            //遍历比对有效值
            for (int i =0;i<value_array.length;i++)
            {
                //存在一致跳出循环,赋值isFlag=true
                if(value_array[i].equals(value))
                {
                    isFlag = true;
                    break;
                }
            }
            //返回是否存在boolean
            return isFlag;
        }
    }

    测试:

  • 相关阅读:
    hdu 3665 Seaside
    hdu 3664 Permutation Counting
    hdu 3661 Assignments
    2017-2018 ACM-ICPC, NEERC, Southern Subregional Contest, qualification stage (Online Mirror, ACM-ICPC Rules, Teams Preferred) E. Packmen
    2017-2018 ACM-ICPC, NEERC, Southern Subregional Contest, qualification stage (Online Mirror, ACM-ICPC Rules, Teams Preferred) I. Noise Level
    2017-2018 ACM-ICPC, NEERC, Southern Subregional Contest, qualification stage (Online Mirror, ACM-ICPC Rules, Teams Preferred) H. Load Testing
    2017-2018 ACM-ICPC, NEERC, Southern Subregional Contest, qualification stage (Online Mirror, ACM-ICPC Rules, Teams Preferred) C C. Sum of Nestings
    Codeforces Round #439 B
    Codeforces Round #439 A
    codeforces 803c
  • 原文地址:https://www.cnblogs.com/soft2018/p/10301479.html
Copyright © 2011-2022 走看看