一. 引入依赖
<!--引入jsr303(支持验证框架)-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-validation</artifactId>
</dependency>
</dependencies>
JSR-303是Java EE 6中的一项子规范,叫做Bean Validation
二. 添加验证规则
2.1 添加在JavaBean上面
import javax.validation.constraints.*;
public class TestDto {
@NotEmpty(message = "学号不能为空")
@Size(min = 6,max = 6,message = "学好必须是六位")
private String e_id;
@NotEmpty(message = "名字不能为空")
private String e_name;
@NotNull(message ="成绩不能为null")
@Min(value = 0,message = "成绩不得为负数")
@Max(value = 100,message = "成绩最大是100")
private Integer e_score;
public String getE_id() {
return e_id;
}
public void setE_id(String e_id) {
this.e_id = e_id;
}
public String getE_name() {
return e_name;
}
public void setE_name(String e_name) {
this.e_name = e_name;
}
public Integer getE_score() {
return e_score;
}
public void setE_score(Integer e_score) {
this.e_score = e_score;
}
}
public class LoginDto {
//@NotEmpty仅针对String ,集合等
@NotEmpty(message = "账号不得为空")
private String u_id;
@NotEmpty(message = "密码不得为空")
@Size(min = 6,max = 15,message = "密码必须为6-15")
private String u_pwd;
public String getU_id() {
return u_id;
}
public void setU_id(String u_id) {
this.u_id = u_id;
}
public String getU_pwd() {
return u_pwd;
}
public void setU_pwd(String u_pwd) {
this.u_pwd = u_pwd;
}
}
添加在Java Bean上面的验证在使用的时候必须在作为参数的javaBean前面添加@Validated注解,才能生效
@RestController
public class LoginController {
@PostMapping("/login")
//对于JavaBean的验证,在这里加注解@Validated
public Result doLogin(@Validated @RequestBody LoginDto dto){
return Result.ok();
}
}
2.2 添加在控制器参数上
@RestController
@Validated//该注解加在类上表示:本类的方法参数如果有限制(约束)注解,将进行验证,
// 后端的验证是必须的,前端的验证时可以通过技术手段跳过的,后端的验证才是保障
public class MyController {
@GetMapping("/say")
public String sayHello(@NotEmpty(message = "名称不能为null") String name,
@NotNull(message = "年龄必须要填写")
@Min(value=16,message = "最小不能小于16岁")Integer age){
return "hello"+name;
}
@GetMapping("/test")
public Result testDto(@Validated TestDto testDto){
return Result.ok("登陆成功");
}
}
注意:在类上添加了@Validated注解,但是在参数是javaBean的时候还得在参数前添加@Validated注解。
三. 开发全局异常处理
import lombok.extern.slf4j.Slf4j;
import org.springframework.validation.BindException;
import org.springframework.validation.BindingResult;
import org.springframework.validation.FieldError;
import org.springframework.web.bind.MethodArgumentNotValidException;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.RestControllerAdvice;
import javax.validation.ConstraintViolation;
import javax.validation.ConstraintViolationException;
import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;
@Slf4j
@RestControllerAdvice//该注解说明本类是一个RestController的拦截器,
// 还可以对controller处理方法添加额外逻辑,做增强处理
public class DemoControllerAdvice {
//该注解说明本方法是一个异常处理器,即当被拦截的controller处理方法发生指定的异常时,即由本方法处理
@ExceptionHandler(ConstraintViolationException.class)
public Result handleConstraintViolationException(ConstraintViolationException e){
log.error("参数不匹配",e);
Set<ConstraintViolation<?>> set = e.getConstraintViolations();//获取验证错误集合
//将验证错误集合中,每一个错误的信息取出来,组成一个新的集合,再将新集合中的元素用”,“连接成一个字符串,返回这个字符串
String msg = set.stream().map(item->item.getMessage()).collect(Collectors.joining(","));
msg.substring(0,msg.length()-1);
return Result.err(Result.CODE_ERR_SYS,msg);
}
//邦json没绑好异常(post请求)
@ExceptionHandler(MethodArgumentNotValidException.class)
public Result handleMethodArgumentNotValidException(MethodArgumentNotValidException e){
log.error("参数不匹配",e);
//获取参数绑定结果(包括绑定错误信息)
BindingResult bindingResult = e.getBindingResult();
//获取属性错误集合
List<FieldError> fieldErrorList = bindingResult.getFieldErrors();
String errMsg = fieldErrorList.stream()
.map(fieldError->fieldError.getField()+":"+fieldError.getDefaultMessage())
.collect(Collectors.joining(","));
return Result.err(Result.CODE_ERR_SYS,errMsg);
}
//绑普通字符串没绑好异常
@ExceptionHandler(BindException.class)
public Result handleBindException(BindException e){
log.error("参数不匹配",e);
//获取参数绑定结果(包括绑定错误信息)
BindingResult bindingResult = e.getBindingResult();
//获取属性错误集合
List<FieldError> fieldErrorList = bindingResult.getFieldErrors();
String errMsg = fieldErrorList.stream()
.map(fieldError->fieldError.getField()+":"+fieldError.getDefaultMessage())
.collect(Collectors.joining(","));
return Result.err(Result.CODE_ERR_SYS,errMsg);
}
}
三个注解:
①:Slf4j:lombok自带的打印日志信息的一个注解,上面的log.error();就是方便程序员排查错误。

②:RestControllerAdvice:该注解说明本类是一个RestController的拦截器,还可以对controller处理方法添加额外逻辑,做增强处理(AOP的实现,try...catch...)
③:@ExceptionHandler:该注解说明本方法是一个异常处理器,即当被拦截的controller处理方法发生指定的异常时,即由本方法处理
三个异常:
①:ConstraintViolationException:get请求传参不匹配
②:MethodArgumentNotValidException:post请求传递json串异常
③:BindException:get请求传递javaBean异常
除过这些,还有对自己定义异常的处理:
//处理自定义系统异常
@ExceptionHandler(SysException.class)
public Result handleSysException(SysException e){
log.error("系统错误",e);
return Result.err(Result.CODE_ERR_SYS,"系统维护中");
}
//处理自定义业务异常
@ExceptionHandler(BusinessException.class)
public Result handleBusinessException(BusinessException e){
return Result.err(Result.CODE_ERR_BUSINESS,e.getMessage());
}
//参数格式异常
@ExceptionHandler(TypeMismatchException.class)
public Result handleTypeMismatchException(TypeMismatchException e){
log.error("系统错误",e);
return Result.err(Result.CODE_ERR_BUSINESS,"系统维护中");
}
//处理遗留的异常
@ExceptionHandler(Exception.class)
public Result handleException(Exception e){
log.error("系统错误",e);
return Result.err(Result.CODE_ERR_BUSINESS,"系统维护中");
}