一、什么是数据校验
- 定义:数据校验主要用于验证客户输入的数据是否合法,比如客户登录时,用户名不能为空,或者不能超出指定长度等要求,这就叫做数据校验。
- 数据校验分为客户端校验和服务端校验
客户端校验:即js校验,前端的js校验可以涵盖大部分的校验职责,如用户名唯一性,生日格式,邮箱格式校验等等常用的校验。
服务端校验:为了避免用户绕过浏览器,使用http工具直接向后端请求一些违法数据,服务端的数据校验也是必要的,可以防止脏数据落到数据库中;springmvc使用validation校验,struts2使用validation校验。都有自己的一套校验规则。
二、springmvc的validation校验
- Springmvc本身没有校验功能,它使用hibernate的校验框架,hibernate的校验框架和orm没有关系。
2.1、引入hibernate的校验框架相关依赖包
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-validator</artifactId>
<version>6.0.16.Final</version>
</dependency>
<dependency>
<groupId>org.jboss.logging</groupId>
<artifactId>jboss-logging</artifactId>
<version>3.3.2.Final</version>
</dependency>
<dependency>
<groupId>javax.validation</groupId>
<artifactId>validation-api</artifactId>
<version>2.0.1.Final</version>
</dependency>
2.2、在resources文件夹下面创建validation.properties配置文件
user.name.size=用户姓名字符串长度必须在3到6个字符之间
user.age.value=用户年龄必须在0到150之间
user.iphone.length=用户手机号码长度必须是11,且手机号码格式符合规范
user.email.error=用户邮箱要符合常见的邮箱格式
2.3、springmvc.xml配置validation数据校验器
<!--配置springmvc数据校验器工厂bean-->
<bean id="validationFactory" class="org.springframework.validation.beanvalidation.LocalValidatorFactoryBean">
<!--配置工厂bean要生产的Validator对象-->
<property name="providerClass" value="org.hibernate.validator.HibernateValidator"/>
<property name="validationMessageSource" ref="validationSource"/>
</bean>
<!--配置validationSource-->
<bean id="validationSource" class="org.springframework.context.support.ReloadableResourceBundleMessageSource">
<!--配置资源路径-->
<property name="basenames">
<list>
<value>validation</value>
</list>
</property>
<!--指定文件编码-->
<property name="fileEncodings" value="utf-8"/>
<!--对资源文件内容设置 -->
<property name="cacheSeconds" value="120"/>
</bean>
<!--springmvc注解驱动注册校验器工厂bean-->
<mvc:annotation-driven validator="validationFactory"/>
- validationSource:引入前面的validation.properties配置文件
- validationFactory:springmvc数据校验器工厂bean,用于生成HibernateValidator实例并引进validationSource配置源文件
2.4、自定义实体类User
public class User {
@Size(min = 3,max = 6,message = "{user.name.size}")
private String name;
@NotNull
@Min(value = 0,message = "{user.age.value}")
@Max(value = 150,message = "{user.age.value}")
private int age;
@Pattern(regexp = "((^(13|15|18)[0-9]{9}$)|(^0[1,2]{1}\\\\d{1}-?\\\\d{8}$)|(^0[3-9] {1}\\\\d{2}-?\\\\d{7,8}$)|(^0[1,2]{1}\\\\d{1}-?\\\\d{8}-(\\\\d{1,4})$)|(^0[3-9]{1}\\\\d{2}-? \\\\d{7,8}-(\\\\d{1,4})$))"
,message = "{user.iphone.length}")
private String iphone;
@Email( regexp = "^([a-z0-9A-Z]+[-|\\\\.]?)+[a-z0-9A-Z]@([a-z0-9A-Z]+(-[a-z0-9A-Z]+)?\\\\.)+[a-zA-Z]{2,}$"
,message = "{user.email.error}")
private String email;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
2.5、MyController处理器类
@RequestMapping("/register")
public String doRegister(@Validated User user, BindingResult result, Model model){
if (result.hasErrors()){
List<ObjectError> allErrors = result.getAllErrors();
for (ObjectError objectError : allErrors) {
System.out.println(objectError);
if (objectError.equals(result.getFieldError("name"))){
model.addAttribute("name_error",objectError.getDefaultMessage());
}else if (objectError.equals(result.getFieldError("age"))){
model.addAttribute("age_error",objectError.getDefaultMessage());
}else if(objectError.equals(result.getFieldError("iphone"))){
model.addAttribute("iphone_error",objectError.getDefaultMessage());
}else if(objectError.equals(result.getFieldError("email"))){
model.addAttribute("email_error",objectError.getDefaultMessage());
}
}
return "register";
}
return "register";
}
- objectError.getDefaultMessage():获取@Size(min = 3,max = 6,message = “{user.name.size}”)的message内容,即对应的配置文件中user.name.size的内容。
- 注意:参数user前需要加上@Validated注解,表明需要spring对其进行校验,而校验的信息会存放到其后的BindingResult中。注意,必须相邻,如果有多个参数需要校验,形式可以如下。doRegister(@Validated User user, BindingResult result,@Validated Bar bar, BindingResult barBindingResult);即一个校验类对应一个校验结果。
2.6、register.jsp内容
<body>
<form action="/my/register" method="post">
姓名:<input type="text" name="name"/>${name_error}<br>
年龄:<input type="text" name="age"/>${age_error}<br>
电话:<input type="text" name="iphone"/>${iphone_error}<br>
邮箱:<input type="text" name="email"/>${email_error}<br>
<button type="submit">登录</button>
</form>
</body>
2.7、测试结果能够成功校验
2.8、常用校验规则
三、分组校验
3.1、何为分组校验
- 场景分析:同一个pojo可以被多个Controller使用,此时会有问题,即:不同的Controller方法对同一个pojo进行校验,此时这些校验信息是共享在这不同的Controller方法中,但是实际上每个Controller方法可能需要不同的校验,在这种情况下,就需要使用分组校验来解决这种问题。
3.2、分组校验的具体实现
1、定义分组
- 接口类只作为这个分组标识来使用
2、使用分组
3、controller方法