springboot-数据验证及全局异常处理

一. 引入依赖

<!--引入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,"系统维护中");
    }

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值