1、前言
在控制器类的方法里自己写校验逻辑代码当然也可以,只是代码比较丑陋,有点“low”。业界有更好的处理方法,分别阐述如下。
2、PathVariable校验
用法是:路径变量:正则表达式。当请求URI不满足正则表达式时,客户端将收到404错误码。不方便的地方是,不能通过捕获异常的方式,向前端返回统一的、自定义格式的响应参数。
3、方法参数校验
@GetMapping("/validate1")
@ResponseBody
public String validate1(
@Size(min = 1,max = 10,message = "姓名长度必须为1到10")@RequestParam("name") String name,
@Min(value = 10,message = "年龄最小为10")@Max(value = 100,message = "年龄最大为100") @RequestParam("age") Integer age) {
return "validate1";
}
如果前端传递的参数不满足规则,则抛出异常。注解Size、Min、Max来自validation-api.jar,更多注解参见相关标准小节。
4、表单对象/VO对象校验
当参数是VO时,可以在VO类的属性上添加校验注解。
其中,Future注解要求必须是相对当前时间来讲“未来的”某个时间。
5、自定义校验规则
5.1 自定义注解校验
需要自定义一个注解类和一个校验类。
使用我们自定义的注解:
5.2 分组校验
/**
* 使用Defaul分组进行验证
* @param resume
* @return
*/
@PostMapping("/validate5")
public String addUser(@Validated(value = Resume.Default.class) @RequestBody Resume resume) {
return "validate5";
}
/**
* 使用Default、Update分组进行验证
* @param resume
* @return
*/
@PutMapping("/validate6")
public String updateUser(@Validated(value = {Resume.Update.class, Resume.Default.class}) @RequestBody Resume resume) {
return "validate6";
}
建立了两个分组,名称分别为Default、Update。POST方法提交时使用Defaut分组的校验规则,PUT方法提交时同时使用两个分组规则。
6、异常拦截器
通过设置全局异常处理器,统一向前端返回校验失败信息。
import com.scj.springbootdemo.WebResult;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.util.CollectionUtils;
import org.springframework.validation.ObjectError;
import org.springframework.web.bind.MethodArgumentNotValidException;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseBody;
import javax.validation.ConstraintViolation;
import javax.validation.ConstraintViolationException;
import java.util.List;
import java.util.Set;
/**
* 全局异常处理器
*/
@ControllerAdvice
public class GlobalExceptionHandler {
private Logger logger = LoggerFactory.getLogger(GlobalExceptionHandler.class);
/**
* 用来处理bean validation异常
* @param ex
* @return
*/
@ExceptionHandler(ConstraintViolationException.class)
@ResponseBody
public WebResult resolveConstraintViolationException(ConstraintViolationException ex){
WebResult errorWebResult = new WebResult(WebResult.FAILED);
Set