SpringBoot 全局异常拦截捕获处理
个人学习用-搬运原文链接
1、需求
前后端分离项目中,后端通常是以json形式将数据返回给前端。此时,如果服务器内部出现异常,如何对内部异常处理后响应给前端呢?
2、实现方式
结合 @RestControllerAdvice 和 @ExceptionHandler 来捕获绝大部分异常,然后通过自定义的全局数据返回对象统一返回Json形式给前端。
@RestControllerAdvice: 增强类;
@ExceptionHandler: 标注异常处理方法,包括异常类型。
3、具体步骤
3.1、自定义 全局数据返回对象
import com.fasterxml.jackson.annotation.JsonIgnore;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import java.io.Serializable;
/**
* 接口返回数据格式
*/
@Data
@ApiModel(value = "接口返回对象", description = "接口返回对象")
public class Result<T> implements Serializable {
/**
* 状态码
*/
private static final Integer HANDLE_OK = 200;
private static final Integer CLIENT_NOT_FOUND_404 = 404;
private static final Integer CLIENT_NO_AUTH_401 = 401;
private static final Integer SERVER_ERROR_500 = 500;
private static final Integer SERVER_NO_AUTH_510 = 200;
private static final long serialVersionUID = 1L;
/**
* 成功标志
*/
@ApiModelProperty(value = "成功标志")
private boolean success = true;
/**
* 返回处理消息
*/
@ApiModelProperty(value = "返回处理消息")
private String message = "";
/**
* 返回代码(状态码)
*/
@ApiModelProperty(value = "返回代码")
private Integer code = 0;
/**
* 返回数据对象 data
*/
@ApiModelProperty(value = "返回数据对象")
private T result;
/**
* 时间戳
*/
@ApiModelProperty(value = "时间戳")
private long timestamp = System.currentTimeMillis();
public Result() {
}
/**
* 兼容VUE3版token失效不跳转登录页面
* @param code
* @param message
*/
public Result(Integer code, String message) {
this.code = code;
this.message = message;
}
public Result<T> success(String message) {
this.message = message;
this.code = HANDLE_OK;
this.success = true;
return this;
}
public static <T> Result<T> ok() {
Result<T> r = new Result<T>();
r.setSuccess(true);
r.setCode(HANDLE_OK);
return r;
}
public static <T> Result<T> ok(String msg) {
Result<T> r = new Result<T>();
r.setSuccess(true);
r.setCode(HANDLE_OK);
r.setMessage(msg);
r.setResult((T) msg);
return r;
}
public static <T> Result<T> ok(T data) {
Result<T> r = new Result<T>();
r.setSuccess(true);
r.setCode(HANDLE_OK);
r.setResult(data);
return r;
}
public static <T> Result<T> ok(String msg, T data) {
Result<T> r = new Result<T>();
r.setSuccess(true);
r.setCode(HANDLE_OK);
r.setMessage(msg);
r.setResult(data);
return r;
}
public static <T> Result<T> error(String msg) {
return error(SERVER_ERROR_500, msg);
}
public static <T> Result<T> error(String msg, T data) {
Result<T> r = new Result<T>();
r.setSuccess(false);
r.setCode(SERVER_ERROR_500);
r.setMessage(msg);
r.setResult(data);
return r;
}
public static <T> Result<T> error(int code, String msg) {
Result<T> r = new Result<T>();
r.setCode(code);
r.setMessage(msg);
r.setSuccess(false);
return r;
}
public Result<T> error500(String message) {
this.message = message;
this.code = SERVER_ERROR_500;
this.success = false;
return this;
}
/**
* 无权限访问返回结果
*/
public static <T> Result<T> noauth(String msg) {
return error(SERVER_NO_AUTH_510, msg);
}
}
3.2、自定义 全局异常捕获处理类
1. 清楚具体异常类型时
在类上,通过 @RestControllerAdvice(annotations = Controller.class) 注解标注全局异常处理类,指定处理带有@Controller注解的类,也就是controller层的所有方法。
在方法上,通过 @ExceptionHandler({ArithmeticException.class}) 标注异常处理方法以及方法所处理的异常类型。
@Slf4j
@RestControllerAdvice
public class ExceptionsHandler {
@ExceptionHandler({ArithmeticException.class})
public Result<String> arithmeticException(ArithmeticException ex) {
log.error("除数不能为0:{} ", ex.getMessage(), ex);
return Result.error(400, "除数不能为0");
}
}
2. 不清楚具体异常类型时,直接捕获异常的公共类 Exception
@ControllerAdvice(annotations = Controller.class)
public class ExceptionAdvice {
private static final Logger logger = LoggerFactory.getLogger(ExceptionAdvice.class);
@ExceptionHandler(Exception.class)
public void handleException(Exception e, HttpServletRequest request, HttpServletResponse response) throws IOException {
// 打印异常日志
logger.error(e.getMessage());
StackTraceElement[] stackTrace = e.getStackTrace();
for (StackTraceElement element : stackTrace) {
logger.error(element.toString());
}
// 返回处理结果,要判断异常发生的请求是普通请求(返回页面),还是异步请求(返回json数据)
String xRequestedWith = request.getHeader("x-requested-with");
// 异步请求
if (xRequestedWith.equals("XMLHttpRequest")) {
response.setContentType("application/plain;charset=utf-8");
PrintWriter writer = response.getWriter();
writer.write(CommunityUtil.getJSONString(1, "服务器发生异常!"));
} else {
response.sendRedirect(request.getContextPath() "/error");
}
}
}
3.3、编写测试方法
编写测试方法(会出现异常的方法)
@RestController
@RequestMapping("/exception")
public class ExceptionTestController {
@GetMapping("/test")
public Result<Integer> testException(int num) {
int res = 23 / num;
return Result.ok(res);
}
}
3.4、测试
异步请求: 返回json数据
普通方法: 返回页面
这篇好文章是转载于:学新通技术网
- 版权申明: 本站部分内容来自互联网,仅供学习及演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,请提供相关证据及您的身份证明,我们将在收到邮件后48小时内删除。
- 本站站名: 学新通技术网
- 本文地址: /boutique/detail/tanhgbhehj
系列文章
更多
同类精品
更多
-
photoshop保存的图片太大微信发不了怎么办
PHP中文网 06-15 -
Android 11 保存文件到外部存储,并分享文件
Luke 10-12 -
word里面弄一个表格后上面的标题会跑到下面怎么办
PHP中文网 06-20 -
《学习通》视频自动暂停处理方法
HelloWorld317 07-05 -
photoshop扩展功能面板显示灰色怎么办
PHP中文网 06-14 -
微信公众号没有声音提示怎么办
PHP中文网 03-31 -
excel下划线不显示怎么办
PHP中文网 06-23 -
怎样阻止微信小程序自动打开
PHP中文网 06-13 -
excel打印预览压线压字怎么办
PHP中文网 06-22 -
TikTok加速器哪个好免费的TK加速器推荐
TK小达人 10-01