全局异常处理
默认异常
{
"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;
}
鸣谢
- https://www.cnblogs.com/UncleWang001/p/10949318.html
- https://www.cnblogs.com/yxs-yoko/p/15588690.html










网友评论