美文网首页
[Java] 全局异常处理

[Java] 全局异常处理

作者: 巨馍蘸酱 | 来源:发表于2022-06-28 10:29 被阅读0次

全局异常处理

默认异常

{
  "timestamp": "2022-06-28 19:45:18",
  "status": 500,
  "error": "Internal Server Error",
  "path": "/xxx/api/test/1"
}

期望结构

{
  "msg": "xxx",
  "code": 123,
  "data: object
}

@ControllerAdvice

@ControllerAdvice 通常用来定义 @ExceptionHandler (异常处理) @InitBinder (数据绑定) 以及 @ModelAttribute (全局属性设置) 适用于所有 @RequestMapping 的方法

限定控制器

  • basePackages 指定一个或多个包,这些包及其子包下的所有 Controller 都被该 @ControllerAdvice 管理[1]
  • assignableTypes 指定一个或多个 Controller 类,这些类被该 @ControllerAdvice 管理[1]
  • annotations 指定一个或多个注解,被这些注解所标记的 Controller 会被该 @ControllerAdvice 管理[1]

统一处理处理 web 端异常

package com.example.exception;

import com.example.constant.ResponseResult;
import lombok.extern.slf4j.Slf4j;
import org.springframework.http.HttpStatus;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.WebDataBinder;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.servlet.ModelAndView;

/**
 * @author dk
 * @create 2022-06-29 10:09 AM
 */
@Slf4j
@ControllerAdvice(basePackages = {"com.example.web"}) // 处理 web
public class ExceptionHandlerAdvice {

    /**
     * 应用到所有@RequestMapping注解方法,在其执行之前初始化数据绑定器
     */
    @InitBinder
    public void initBinder(WebDataBinder binder) {

    }

    /**
     * 把值绑定到Model中,使全局@RequestMapping可以获取到该值
     */
    @ModelAttribute
    public void addAttributes(Model model) {

    }

    /**
     * 全局异常捕捉处理
     */
    @ExceptionHandler(value = Exception.class)
    @ResponseBody
    public ResponseResult HandleException(Exception ex){
        log.error("系统异常: ", ex);
        return ResponseResult.error(ex.getLocalizedMessage());
    }

    /**
     * 系统内部业务错误
     */
    @ExceptionHandler(value = BusinessException.class)
    @ResponseStatus(HttpStatus.INTERNAL_SERVER_ERROR)
    public ModelAndView handleBusinessException(BusinessException ex) {
        ModelAndView modelAndView = new ModelAndView();
        modelAndView.setViewName("error");
        modelAndView.addObject("code", ex.getCode());
        modelAndView.addObject("msg", ex.getMsg());
        return modelAndView;
    }
}

@RestControllerAdvice

RestControllerAdvice = ControllerAdvice + ResponseBody
类似: RestController = Controller + ResponseBody

统一处理 api 异常

package com.example.exception;

import com.example.constant.ResponseResult;
import lombok.extern.slf4j.Slf4j;
import org.springframework.http.HttpStatus;
import org.springframework.ui.Model;
import org.springframework.web.bind.WebDataBinder;
import org.springframework.web.bind.annotation.*;

/**
 * @author dk
 * @create 2022-06-29 10:09 AM
 */
@Slf4j
@RestControllerAdvice(basePackages = {"com.example.api"}) // 处理 api
public class ExceptionHandlerRestAdvice {
    /**
     * 全局异常捕捉处理
     */
    @ExceptionHandler(value = Exception.class)
    public ResponseResult HandleException(Exception ex){
        log.error("系统异常: ", ex);
        return ResponseResult.error(ex.getLocalizedMessage());
    }

    /**
     * 系统内部业务错误
     */
    @ExceptionHandler(value = BusinessException.class)
    @ResponseStatus(HttpStatus.INTERNAL_SERVER_ERROR)
    public ResponseResult handleBusinessException(BusinessException ex) {
        log.error("业务异常: ", ex);
        return ResponseResult.error(ex.getCode(), ex.getMsg());
    }
}

其他基础类

BusinessException

package com.example.exception;

import lombok.Getter;

/**
 * @author dk
 * @create 2022-06-28 7:19 PM
 */
@Getter
public class BusinessException extends RuntimeException {

    private int code;
    private String msg;

    public BusinessException(ExceptionEnum exceptionEnum) {
        this.code = exceptionEnum.getCode();
        this.msg = exceptionEnum.getMessage();
    }
    public BusinessException(int code, String msg) {
        this.code = code;
        this.msg = msg;
    }
    public BusinessException(int code, String message, Object... args) {
        this.code = code;
        this.msg = String.format(message, args);
    }
}

ExceptionEnum

package com.example.exception;

import lombok.Getter;

/**
 * @author dk
 * @create 2022-06-29 9:45 AM
 */
@Getter
public enum ExceptionEnum {

    /**
     * code: 异常编码
     * message:异常信息
     */
    SUCCESS(200, " 操作成功!"),
    ERROR(0, "操作失败!"),
    SERVER_ERROR(500, "服务器内部错误!"),
    SERVICE_BUSY(503, "服务器正忙,请稍后再试!");

    private int code;
    private String message;
    ExceptionEnum(int code, String message) {
        this.code = code;
        this.message = message;
    }

}

ResponseResult

package com.example.constant;

import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Getter;
import lombok.Setter;

import java.io.Serializable;

/**
 * @author dk
 * @create 2022-06-28 7:25 PM
 */
@Getter
@Setter
@ApiModel(value="ResponseResult对象", description="响应结果对象")
public class ResponseResult<T> implements Serializable {

    private static final long serialVersionUID = 1L;

    @ApiModelProperty(value = "状态码")
    private int code;

    @ApiModelProperty(value = "提示信息")
    private String msg;

    @ApiModelProperty(value = "响应数据")
    private T data;
}

鸣谢


  1. https://blog.csdn.net/user2025/article/details/105458842

相关文章

网友评论

      本文标题:[Java] 全局异常处理

      本文链接:https://www.haomeiwen.com/subject/uoetbrtx.html