全局异常处理器

1.全局异常处理器

在项目中自定义一个全局异常处理器,在异常处理器上加上注解 @ControllerAdvice,可以通过属性annotations指定拦截哪一类的Controller方法。 并在异常处理器的方法上加上注解 @ExceptionHandler 来指定拦截的是那一类型的异常。

例如:

  1. import lombok.extern.slf4j.Slf4j;
  2. import org.springframework.stereotype.Controller;
  3. import org.springframework.web.bind.annotation.ControllerAdvice;
  4. import org.springframework.web.bind.annotation.ExceptionHandler;
  5. import org.springframework.web.bind.annotation.ResponseBody;
  6. import org.springframework.web.bind.annotation.RestController;
  7. import java.sql.SQLIntegrityConstraintViolationException;
  8. /**
  9. * 全局异常处理
  10. */
  11. @ControllerAdvice(annotations = {RestController.class, Controller.class})
  12. @ResponseBody
  13. @Slf4j
  14. public class GlobalExceptionHandler {
  15. /**
  16. * 异常处理方法
  17. * @return
  18. */
  19. @ExceptionHandler(SQLIntegrityConstraintViolationException.class)
  20. public R<String> exceptionHandler(SQLIntegrityConstraintViolationException ex){
  21. log.error(ex.getMessage());
  22. if(ex.getMessage().contains("Duplicate entry")){
  23. String[] split = ex.getMessage().split(" ");
  24. String msg = split[2] + "已存在";
  25. return R.error(msg);
  26. }
  27. return R.error("未知错误");
  28. }
  29. }

注解说明:

  1. 上述的全局异常处理器上使用了的两个注解 [@ControllerAdvice ](/ControllerAdvice ) , [@ResponseBody ](/ResponseBody ) , 他们的作用分别为:
  2. [@ControllerAdvice ](/ControllerAdvice ) : 指定拦截那些类型的控制器;
  3. @ResponseBody: 将方法的返回值 R 对象转换为json格式的数据, 响应给页面;
  4. 上述使用的两个注解, 也可以合并成为一个注解 [@RestControllerAdvice ](/RestControllerAdvice )

springboot项目中集成全局异常全局处理器,把这个异常类注入到容器管理
Snipaste_2022-01-19_15-02-07.png
spring.factories内容:

  1. org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
  2. com.heima.common.exception.ExceptionCatch,\

2.自定义异常返回类型

  1. public class Result<T> {
  2. private int code;
  3. private String msg;
  4. private T data;
  5. /**
  6. * 请求成功时调用
  7. * @param data
  8. * @return
  9. */
  10. public static <T> Result<T> success(T data){
  11. return new Result<T>(data);
  12. }
  13. public static <T> Result<T> error(CodeMsg cm){
  14. return new Result<T>(cm);
  15. }
  16. /**
  17. * 只传入数据默认成功,所以添加默认的code和msg
  18. * @param data
  19. */
  20. private Result(T data) {
  21. this.code=0;
  22. this.msg="success";
  23. this.data=data;
  24. }
  25. private Result(CodeMsg cm) {
  26. if(cm==null){
  27. return;
  28. }
  29. this.code=cm.getCode();
  30. this.msg=cm.getMsg();
  31. }
  32. public int getCode() {
  33. return code;
  34. }
  35. public String getMsg() {
  36. return msg;
  37. }
  38. public T getData() {
  39. return data;
  40. }
  41. }
  1. public class CodeMsg {
  2. private int code;
  3. private String msg;
  4. //通用的错误码
  5. public static CodeMsg SUCCESS = new CodeMsg(0, "success");
  6. public static CodeMsg SERVER_ERROR = new CodeMsg(500100, "服务端异常");
  7. public static CodeMsg BIND_ERROR = new CodeMsg(500101, "参数校验异常:%s");
  8. //登录模块 5002XX
  9. public static CodeMsg SESSION_ERROR = new CodeMsg(500210, "Session不存在或者已经失效");
  10. public static CodeMsg PASSWORD_EMPTY = new CodeMsg(500211, "登录密码不能为空");
  11. public static CodeMsg STUDENTID_EMPTY = new CodeMsg(500212, "学号不能为空");
  12. public static CodeMsg STUDENTID_ERROR = new CodeMsg(500213, "学号格式错误");
  13. public static CodeMsg STUDENTIDE_NOT_EXIST = new CodeMsg(500214, "学号不存在");
  14. public static CodeMsg PASSWORD_ERROR = new CodeMsg(500215, "密码错误");
  15. public int getCode() {
  16. return code;
  17. }
  18. public String getMsg() {
  19. return msg;
  20. }
  21. public CodeMsg fillArgs(Object... args) {
  22. int code = this.code;
  23. String message = String.format(this.msg, args);
  24. return new CodeMsg(code, message);
  25. }
  26. private CodeMsg(int code,String msg) {
  27. this.code = code;
  28. this.msg = msg;
  29. }
  30. }

3.自定义异常类

  1. public class GlobalException extends RuntimeException{
  2. private static final long serialVersionUID = 1L;
  3. private CodeMsg cm;
  4. public GlobalException(CodeMsg cm) {
  5. super(cm.toString());
  6. this.cm = cm;
  7. }
  8. public CodeMsg getCm() {
  9. return cm;
  10. }
  11. }

4.使用自定义异常类

使用自定义异常类实例

  1. if(user == null) {
  2. throw new GlobalException(CodeMsg.STUDENTIDE_NOT_EXIST);
  3. }