- 在 Web 应用三层架构体系中,表述层负责接收浏览器提交的数据,我们需要在表述层对数据进行检查,将错误的数据隔绝在业务逻辑层之外。
校验概述
- JSR 303 是 Java 为 Bean 数据合法性校验提供的标准框架,它已经包含在 JavaEE 6.0 标准中。
- JSR 303 通过
在 Bean 属性上标注类似于 @NotNull、@Max 等标准的注解指定校验规则,并通过标准的验证接口对Bean进行验证。
| 注解 | 规则 |
|---|---|
| @Null | 标注值必须为 null |
| @NotNull | 标注值不可为 null |
| @AssertTrue | 标注值必须为 true |
| @AssertFalse | 标注值必须为 false |
| @Min(value) | 标注值必须大于或等于 value |
| @Max(value) | 标注值必须小于或等于 value |
| @DecimalMin(value) | 标注值必须大于或等于 value |
| @DecimalMax(value) | 标注值必须小于或等于 value |
| @Size(max,min) | 标注值大小必须在 max 和 min 限定的范围内 |
| @Digits(integer,fratction) | 标注值值必须是一个数字,且必须在可接受的范围内 |
| @Past | 标注值只能用于日期型,且必须是过去的日期 |
| @Future | 标注值只能用于日期型,且必须是将来的日期 |
| @Pattern(value) | 标注值必须符合指定的正则表达式 |
- JSR 303 只是一套标准,需要提供其实现才可以使用。
- Hibernate Validator 是 JSR 303 的一个参考实现,除支持所有标准的校验注解外,它还支持以下的扩展注解:
| 注解 | 规则 |
|---|---|
| 标注值必须是格式正确的 Email 地址 | |
| @Length | 标注值字符串大小必须在指定的范围内 |
| @NotEmpty | 标注值字符串不能是空字符串 |
| @Range | 标注值必须在指定的范围内 |
-
Spring 4.0 版本已经拥有自己独立的数据校验框架,同时支持 JSR 303 标准的校验框架。
-
Spring 在进行数据绑定时,可同时调用校验框架完成数据校验工作。
-
在SpringMVC 中,可直接通过注解驱动
@EnableWebMvc的方式进行数据校验。 -
Spring 的 LocalValidatorFactoryBean 既实现了 Spring 的 Validator 接口,也实现了 JSR 303 的 Validator 接口。只要在Spring容器中定义了一个LocalValidatorFactoryBean,即可将其注入到需要数据校验的 Bean中。
-
Spring本身并没有提供JSR 303的实现,所以必须将JSR 303的实现者的jar包放到类路径下。
-
配置 @EnableWebMvc后,SpringMVC 会默认装配好一个 LocalValidatorFactoryBean,通过在处理方法的入参上标注 @Validated 注解即可让 SpringMVC 在完成数据绑定后执行数据校验的工作。
需要的依赖
xml
<!-- 校验注解 -->
<dependency>
<groupId>jakarta.platform</groupId>
<artifactId>jakarta.jakartaee-web-api</artifactId>
<version>9.1.0</version>
<scope>provided</scope>
</dependency>
<!-- 校验注解实现-->
<!-- https://mvnrepository.com/artifact/org.hibernate.validator/hibernate-validator -->
<dependency>
<groupId>org.hibernate.validator</groupId>
<artifactId>hibernate-validator</artifactId>
<version>8.0.0.Final</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.hibernate.validator/hibernate-validator-annotation-processor -->
<dependency>
<groupId>org.hibernate.validator</groupId>
<artifactId>hibernate-validator-annotation-processor</artifactId>
<version>8.0.0.Final</version>
</dependency>
实体类
java
package com.cool.pojo;
import jakarta.validation.constraints.Email;
import jakarta.validation.constraints.Min;
import jakarta.validation.constraints.NotBlank;
import jakarta.validation.constraints.Past;
import lombok.Data;
import org.hibernate.validator.constraints.Length;
import java.util.Date;
/**
* name:不为null、不为空字符串
* 字符串不为空:@NotBlank
* 集合不为空:@NotEmpty
* 包装类型不为空:@NotNull
*
* password:长度大于6
*/
@Data
public class User {
@NotBlank
private String name;
@Length(min = 6, max = 20)
private String password;
@Min(1)
private int age;
@Email
private String email;
@Past
private Date birthday;
}
controller
java
package com.cool.controller;
import com.cool.pojo.User;
import org.springframework.validation.BindingResult;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import java.util.HashMap;
import java.util.Map;
@RestController
@RequestMapping("user")
public class UserController {
/**
* 步骤1:实体类属性添加校验注解
* 步骤2:handler(@Validated 实体类对象){}
* 细节:
* param、json 校验注解都有效果
* 只不过,json参数的话,需要用 @RequestBody 修饰形参哦!
*
* 这里有个天坑:如果不符合校验规则,会直接向前端抛出异常
* 解决办法:
* handler(@Validated 实体类对象, BindingResult request){}
* 多加一个 BindingResult request 参数,
* 此参数,必须紧挨着 @Validated 实体类对象,否则此参数不管用
*/
@PostMapping("register")
public Object register(@Validated @RequestBody User user, BindingResult result){
System.out.println("user= " + user);
if(result.hasErrors()){
// 有错误的话,就不直接返回给前端了,可以在这里自定义内容,返回给前端
Map data = new HashMap();
data.put("code", 400);
data.put("msg", "参数校验异常");
return data;
}
return user;
}
}