Spring校验注解异常统一处理类

こ雲淡風輕ζ 提交于 2020-05-06 00:03:20

@ControllerAdvice

该注解为统一异常处理的核心

是一种作用于控制层的切面通知(Advice),该注解能够将通用的@ExceptionHandler、@InitBinder和@ModelAttributes方法收集到一个类型,并应用到所有控制器上

该类中的设计思路:

  • 使用@ExceptionHandler注解捕获指定或自定义的异常;

  • 使用@ControllerAdvice集成@ExceptionHandler的方法到一个类中;

  • 必须定义一个通用的异常捕获方法,便于捕获未定义的异常信息;

  • 自定一个异常类,捕获针对项目或业务的异常;

  • 异常的对象信息补充到统一结果枚举中;

 

自定义全局异常类

import com.example.demo.util.R;
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;

/**
 * 全局异常处理类
 */
@ControllerAdvice
public class CommonExceptionHandler {

    /**
     * 通用异常处理
     * @param ex
     * @return
     */
    @ExceptionHandler(Exception.class)
    @ResponseBody
    public R exceptionHandler(Exception ex) {
        //输出异常信息
        ex.printStackTrace();
        //处理校验注解异常信息
        if (ex instanceof MethodArgumentNotValidException) {
            MethodArgumentNotValidException mex = (MethodArgumentNotValidException) ex;
            return R.failed(mex.getBindingResult().getFieldErrors().get(0).getDefaultMessage());
        } else {
            return R.failed(ex.getMessage());
        }
    }

    /**
     * 单独针对某个异常处理
     * @param e
     * @return
     */
    @ExceptionHandler(NullPointerException.class)
    @ResponseBody
    public R error(NullPointerException e) {
        //输出异常信息
        e.printStackTrace();
        return R.failed("空指针异常");
    }
}

这就是主要核心的代码。

 

SpringBoot代码示例

1.项目目录:

 

2.Controller代码:

import com.example.demo.model.User;
import com.example.demo.util.R;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.validation.Valid;

/**
 * 用户登录控制器
 */
@RestController
@RequestMapping(value = "/user")
public class UserController {

    /**
     * 用户登录
     * @param user
     * @return
     */
    @PostMapping(value = "/login")
    public R login(@Valid @RequestBody User user){
        System.out.println("登录成功!");
        return R.ok(user);
    }

}

 

3.User实体类

import lombok.Data;

import javax.validation.constraints.NotBlank;
import javax.validation.constraints.Size;

/**
 * 用户登录实体类
 */
@Data
public class User {

    @NotBlank(message = "用户名不能为空")
    private String username;

    @NotBlank(message = "密码不能为空")
    @Size(max = 20, min = 6, message = "密码长度在6-20字符之间")
    private String password;

}

 

4.ApiCode枚举

/**
 * api枚举器
 */
public enum ApiCode {

    FAILED(-1L, "操作失败"),
    SUCCESS(0L, "执行成功");

    private final long code;
    private final String msg;

    private ApiCode(long code, String msg) {
        this.code = code;
        this.msg = msg;
    }

    public long getCode() {
        return this.code;
    }

    public String getMsg() {
        return this.msg;
    }

}

 

5.R返回对象参考了mybatis-plus中R对象的设计

import com.example.demo.myenum.ApiCode;
import lombok.Data;

/**
 * 返回对象
 */
@Data
public class R<T> {

    private long code;
    private String msg;
    private T data;

    public R() {
    }

    public static <T> R<T> ok(T data) {
        ApiCode aec = ApiCode.SUCCESS;
        if(data instanceof Boolean && Boolean.FALSE.equals(data)) {
            aec = ApiCode.FAILED;
        }

        return restResult(data, aec.getCode(), aec.getMsg());
    }

    public static <T> R<T> failed(String msg) {
        return restResult(null, ApiCode.FAILED.getCode(), msg);
    }

    private static <T> R<T> restResult(T data, long code, String msg) {
        R<T> apiResult = new R();
        apiResult.setCode(code);
        apiResult.setData(data);
        apiResult.setMsg(msg);
        return apiResult;
    }

}

 

PostMan请求测试

看到这个结果我们的全局统一处理注解校验异常就成功了。

 

Spring字段校验的注解说明

限制 说明
@Null 限制只能为null
@NotNull 限制必须不为null
@AssertFalse 限制必须为false
@AssertTrue 限制必须为true
@DecimalMax(value) 限制必须为一个不大于指定值的数字
@DecimalMin(value) 限制必须为一个不小于指定值的数字
@Digits(integer,fraction) 限制必须为一个小数,且整数部分的位数不能超过integer,小数部分的位数不能超过fraction
@Future 限制必须是一个将来的日期
@Max(value) 限制必须为一个不大于指定值的数字
@Min(value) 限制必须为一个不小于指定值的数字
@Past 限制必须是一个过去的日期
@Pattern(value) 限制必须符合指定的正则表达式
@Size(max,min) 限制字符长度必须在min到max之间
@Past 验证注解的元素值(日期类型)比当前时间早
@NotEmpty 验证注解的元素值不为null且不为空(字符串长度不为0、集合大小不为0)
@NotBlank 验证注解的元素值不为空(不为null、去除首位空格后长度为0),不同于@NotEmpty,@NotBlank只应用于字符串且在比较时会去除字符串的空格
@Email 验证注解的元素值是Email,也可以通过正则表达式和flag指定自定义的email格式


Hiberate Validator还支持以下注解

注解 功能说明
@Email 被注解的元素必须是电子邮箱地址
@Length 被注释的字符串大小必须在指定的范围内
@NotEmpty 注释的字符串必须非空
@Range 注释的元素必须在合适的范围内
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!