简介:
数据验证是作为一个企业级项目架构上设计的最基础的模块,前辈们曾说过:界面上传递到后台的数据没有百分之百值得相信的!为什么这么说呢?往往我们在编写程序的时候都会感觉后台的验证无关紧要,这样就会给别人空子钻。我可以模拟前台发送的请求到后台地址,那么我如果发送一些涉及系统安全的代码到后台,后果一发不可收拾。接下来我们就来讲解下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; } }
三、创建一个名叫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 "验证通过," + "\t名称:" + entity.getName()+ "\t年龄:" + entity.getAge() + "\t邮箱地址:"+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; } }
测试: