1、Validation校验
1、引包:
<dependency>
<groupId>org.hibernate.validator</groupId>
<artifactId>hibernate-validator</artifactId>
<version>6.0.7.Final</version>
</dependency>
<dependency>
<groupId>org.jboss.logging</groupId>
<artifactId>jboss-logging</artifactId>
<version>3.1.0.CR2</version>
</dependency>
<dependency>
<groupId>javax.validation</groupId>
<artifactId>validation-api</artifactId>
<version>2.0.1.Final</version>
</dependency>
</dependencies>
2、首先在annotation-driven的注解驱动配置上添加一个validator属性。
<!-- 1、配置校验器,名称为 validator-->
<mvc:annotation-driven validator="validator" />
3、在springmvc.xml中添加名为validator的校验器配置:
<!--2、添加校验器配置-->
<bean id="validator" class="org.springframework.validation.beanvalidation.LocalValidatorFactoryBean">
<!--指定校验器提供类-->
<property name="providerClass" value="org.hibernate.validator.HibernateValidator" />
<!--指定校验器使用的资源文件,如果不手动指定校验资源文件,则会默认使用classpath下的ValidationMessages.properties-->
<property name="validationMessageSource" ref="messageSource" />
</bean>
4、定义校验错误信息配置文件:
<bean id="messageSource" class="org.springframework.context.support.ReloadableResourceBundleMessageSource">
<!--指定源文件名:basenames(可添加多个资源配置配置文件的配置信息)-->
<property name="basenames">
<list>
<value>classpath:MyValidationMessages</value>
</list>
</property>
<!--指定资源文件编码格式:fileEncodings-->
<property name="fileEncodings" value="UTF-8"/>
<!--指定资源文件缓存时间(单位为秒)-->
<property name="cacheSeconds" value="20" />
</bean>
5、由于该校验机制是给处理器Controller使用的,而加载和调用处理器的是处理器适配器HandlerAdapter,所以要为处理器适配器的配置添加校验器( conversion-service=“conversionService”)
<mvc:annotation-driven conversion-service="conversionService" validator="validator" />
6、在conversion-service属性中配置一个可以将字符串转换为Date类型或者数字类型的Java类
<!--4、在conversion-service属性中配置一个可以将字符串转换为Date类型或者数字类型的Java类(这里的conversionService启用了FormattingConversionServiceFactoryBean类来做类型转换,如果就是使用FormattingConversionServiceFactoryBean类,那么上面的conversion-service属性级bean配置可以不写,因为使用<mvc:annotation-driven/>注解后,默认会注册一个ConversionService,即FormattingConversionServiceFactoryBean)-->
<bean id="conversionService" class="org.springframework.format.support.FormattingConversionServiceFactoryBean" />
7、创建MyValidationMessages.properties文件并且添加错误提示信息
#校验错误提示信息
user.name.length.error = 用户名长度为1到20个字符
user.password.isEmpty=用户密码不能为空
8、
在JavaBean类中添加校验注解信息:
import javax.validation.constraints.NotNull;
import javax.validation.constraints.Size;
public class User {
private Integer id;
@Size(min = 10, max = 20,message = "{user.name.length.error}")
private String account;
@NotBlank(message = "{user.password.isEmpty}")
private String password;
......
......
9、在Controller方法中捕抓校验错误信息(注意在参数前要添加 @Validated ):
@RequestMapping(value = "/add")
@ResponseBody
public Integer add(@RequestBody @Validated User user, BindingResult bindingResult){
List<ObjectError> allErrors = null;
if(bindingResult.hasErrors()){
allErrors = bindingResult.getAllErrors();
for(ObjectError or : allErrors){
//输出错误信息
System.out.println("错误信息为:" + or.getDefaultMessage());
}
return 0;
}
Integer num = userService.saveUser(user);
return num;
}
10、测试结果
输入参数:
{
"account":"zhangsan",
"password":""
}
后台打印结果:
错误信息为:用户密码不能为空
注:
如果项目启动控制台报:
Caused by: java.lang.NoClassDefFoundError: javax/validation/XXXX
或者
Caused by: java.lang.ClassNotFoundException: javax.validation.ClockProvider
则可能是 validation-api 包的版本过低造成的
因为由于hibernate-validator高版本已经不兼容validation-api低版本
解决方案:
将 hibernate-validator 包的版本降低或者将validation-api包的版本降低
2、Validation分组校验
背景:
在日常开发过程中可能会遇到类似此类的情况,当我们编写添加、修改用户的功能时,添加的功能时要求除id外其他参数都不能为空,修改的功能id不能为空。
解决办法:
设置分组校验
配置参照Validation校验配置
设置分组校验步骤:
1、
创建校验组接口(UserGroup1 、UserGroup2):
public interface UserGroup1 {
}
public interface UserGroup2 {
}
2、对User类分配不同的组
public class User {
@NotNull(message = "{user.id.isEmpty}",groups = {UserGroup2.class})
private Integer id;
@Size(min = 1, max = 20,message = "{user.name.length.error}",groups = {UserGroup1.class,UserGroup2.class})
private String account;
@NotBlank(message = "{user.password.isEmpty}",groups = {UserGroup1.class,UserGroup2.class})
private String password;
//set和get方法省略
3、
在Controller类中的方法中需要在实体类面前的@Validated注解中加一个value值:
@RequestMapping(value = "/add")
@ResponseBody
public Integer add(@RequestBody @Validated(value = UserGroup1.class) User user, BindingResult bindingResult){
List<ObjectError> allErrors = null;
if(bindingResult.hasErrors()){
allErrors = bindingResult.getAllErrors();
for(ObjectError or : allErrors){
//输出错误信息
System.out.println("错误信息为:" + or.getDefaultMessage());
}
return 0;
}
Integer num = userService.saveUser(user);
return num;
}
@RequestMapping(value = "/update")
@ResponseBody
public Integer update(@RequestBody @Validated(value = UserGroup2.class) User user, BindingResult bindingResult){
List<ObjectError> allErrors = null;
if(bindingResult.hasErrors()){
allErrors = bindingResult.getAllErrors();
for(ObjectError or : allErrors){
//输出错误信息
System.out.println("错误信息为:" + or.getDefaultMessage());
}
return 0;
}
Integer num = userService.saveUser(user);
return num;
}
4、测试
参数:
{
"account":"zhangsan",
"password":"12345678"
}
调用add方法成功执行
调用update方法:
后台打印结果:
错误信息为:id不能为空
注意:
@NotBlank不能用在Integer类型上,哪些注解能用在哪些类型上要了解清楚