Spring mvc服务端数据校验实现流程详解
B/S系统中对http请求数据的校验多数在客户端进行,这也是出于简单及用户体验性上考虑,但是在一些安全性要求高的系统中服务端校验是不可缺少的,实际上,几乎所有的系统,凡是涉及到数据校验,都需要在服务端进行二次校验。为什么要在服务端进行二次校验呢?这需要理解客户端校验和服务端校验各自的目的。
客户端校验,我们主要是为了提高用户体验,例如用户输入一个邮箱地址,要校验这个邮箱地址是否合法,没有必要发送到服务端进行校验,直接在前端用js进行校验即可。但是大家需要明白的是,前端校验无法代替后端校验,前端校验可以有效的提高用户体验,但是无法确保数据完整性,因为在B/S架构中,用户可以方便的拿到请求地址,然后直接发送请求,传递非法参数。
服务端校验,虽然用户体验不好,但是可以有效的保证数据安全与完整性。
综上,实际项目中,两个一起用。
Spring支持JSR-303验证框架,JSR-303是JAVAEE6中的一项子规范,叫做BeanValidation,官方参考实现是HibernateValidator(与HibernateORM没有关系),JSR-303用于对JavaBean中的字段的值进行验证。
普通校验
普通校验,是这里最基本的用法。
首先,我们需要加入校验需要的依赖:
org.hibernate hibernate-validator 6.1.0.Final
接下来,在SpringMVC的配置文件中配置校验的Bean:
配置时,提供一个LocalValidatorFactoryBean的实例,然后Bean的校验使用HibernateValidator。
这样,配置就算完成了。
接下来,我们提供一个添加学生的页面:
学生编号: 学生姓名: 学生邮箱: 学生年龄:
在这里需要提交的数据中,假设学生编号不能为空,学生姓名长度不能超过10且不能为空,邮箱地址要合法,年龄不能超过150。那么在定义实体类的时候,就可以加入这个判断条件了。
publicclassStudent{ @NotNull privateIntegerid; @NotNull @Size(min=2,max=10) privateStringname; @Email privateStringemail; @Max(150) privateIntegerage; ... }
在这里:
- @NotNull表示这个字段不能为空
- @Size中描述了这个字符串长度的限制
- @Email表示这个字段的值必须是一个邮箱地址
- @Max表示这个字段的最大值
定义完成后,接下来,在Controller中定义接口:
@Controller publicclassStudentController{ @RequestMapping("/addstudent") @ResponseBody publicvoidaddStudent(@ValidatedStudentstudent,BindingResultresult){ if(result!=null){ //校验未通过,获取所有的异常信息并展示出来 ListallErrors=result.getAllErrors(); for(ObjectErrorallError:allErrors){ System.out.println(allError.getObjectName()+":"+allError.getDefaultMessage()); } } } }
在这里:
- @Validated表示Student中定义的校验规则将会生效
- BindingResult表示出错信息,如果这个变量不为空,表示有错误,否则校验通过。
接下来就可以启动项目了。访问jsp页面,然后添加Student,查看校验规则是否生效。
默认情况下,打印出来的错误信息时系统默认的错误信息,这个错误信息,我们也可以自定义。自定义方式如下:
由于properties文件中的中文会乱码,所以需要我们先修改一下IDEA配置,点
File–>Settings->Editor–>FileEncodings,如下:
https://s3-us-west-2.amazonaws.com/secure.notion-static.com/6901df99-8a2e-418b-b791-77cff9fc1bb7/Untitled.png
然后定义错误提示文本,在resources目录下新建一个MyMessage.properties文件,内容如下:
student.id.notnull=id不能为空
student.name.notnull=name不能为空
student.name.length=name最小长度为2,最大长度为10
student.email.error=email地址非法
student.age.error=年龄不能超过150
接下来,在SpringMVC配置中,加载这个配置文件:
classpath:MyMessage
最后,在实体类上,加上校验出错时的消息
publicclassStudent{ @NotNull(message="{student.id.notnull}") privateIntegerid; @NotNull(message="{student.name.notnull}") @Size(min=2,max=10,message="{student.name.length}") privateStringname; @Email(message="{student.email.error}") privateStringemail; @Max(value=150,message="{student.age.error}") privateIntegerage; ... }
配置完成后,如果校验再出错,就会展示我们自己的出错信息了。
分组校验
由于校验规则都是定义在实体类上面的,但是,在不同的数据提交环境下,校验规则可能不一样。例如,用户的id是自增长的,添加的时候,可以不用传递用户id,但是修改的时候则必须传递用户id,这种情况下,就需要使用分组校验。
分组校验,首先需要定义校验组,所谓的校验组,其实就是空接口:
publicinterfaceValidationGroup1{ } publicinterfaceValidationGroup2{ }
然后,在实体类中,指定每一个校验规则所属的组:
publicclassStudent{ @NotNull(message="{student.id.notnull}",groups=ValidationGroup1.class) privateIntegerid; @NotNull(message="{student.name.notnull}",groups={ValidationGroup1.class,ValidationGroup2.class}) @Size(min=2,max=10,message="{student.name.length}",groups={ValidationGroup1.class,ValidationGroup2.class}) privateStringname; @Email(message="{student.email.error}",groups={ValidationGroup1.class,ValidationGroup2.class}) privateStringemail; @Max(value=150,message="{student.age.error}",groups={ValidationGroup2.class}) privateIntegerage; ... }
在group中指定每一个校验规则所属的组,一个规则可以属于一个组,也可以属于多个组。
最后,在接收参数的地方,指定校验组:
@Controller publicclassStudentController{ @RequestMapping("/addstudent") @ResponseBody publicvoidaddStudent(@Validated(ValidationGroup2.class)Studentstudent,BindingResultresult){ if(result!=null){ //校验未通过,获取所有的异常信息并展示出来 ListallErrors=result.getAllErrors(); for(ObjectErrorallError:allErrors){ System.out.println(allError.getObjectName()+":"+allError.getDefaultMessage()); } } } }
配置完成后,属于ValidationGroup2这个组的校验规则,才会生效。
校验注解
@Null被注解的元素必须为null
@NotNull被注解的元素必须不为null
@AssertTrue被注解的元素必须为true
@AssertFalse被注解的元素必须为false
@Min(value)被注解的元素必须是一个数字,其值必须大于等于指定的最小值
@Max(value)被注解的元素必须是一个数字,其值必须小于等于指定的最大值
@DecimalMin(value)被注解的元素必须是一个数字,其值必须大于等于指定的最小值
@DecimalMax(value)被注解的元素必须是一个数字,其值必须小于等于指定的最大值
@Size(max=,min=)被注解的元素的大小必须在指定的范围内
@Digits(integer,fraction)被注解的元素必须是一个数字,其值必须在可接受的范围内
@Past被注解的元素必须是一个过去的日期
@Future被注解的元素必须是一个将来的日期
@Pattern(regex=,flag=)被注解的元素必须符合指定的正则表达式
@NotBlank(message=)验证字符串非null,且长度必须大于0
@Email被注解的元素必须是电子邮箱地址
@Length(min=,max=)被注解的字符串的大小必须在指定的范围内
@NotEmpty被注解的字符串的必须非空
@Range(min=,max=,message=)被注解的元素必须在合适的范围内
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持毛票票。