0 问题
在日常开发中你是否遇到过这样的问题:
当程序出现异常响应给前端的数据格式不是你预期想要的如图所示:
为了返回统一的响应格式,每次代码中都需要手动捕获异常,然后返回统一格式,写法可能会是这样:
import lombok.extern.slf4j.Slf4j;
@Slf4j
@RestController
public class EmployeeController {
@GetMapping("testCustomException/{num}")
@TraceLog
public Result testCustomException(@PathVariable("num") int num) {
try {
int a = 10 / num;
return Result.success().data(a);
} catch (Exception e) {
log.error("error:", e);
return Result.failure(ResultCodeEnum.PARAM_IS_INVALID);
}
}
}
注意:其中的 Result、ResultCodeEnum 类来源于另一片文章介绍的 “Java 统一封装响应结果”
https://blog.youkuaiyun.com/QiuHaoqian/article/details/113493682
但是,你有没有想过,如果每个请求的方法都需要使用 try…catch来包装代码是不是会很臃肿呢?
所以接下来看一下如何实现统一异常处理。
1 实现
第一步:自定义异常类(可选)
package com.haoqian.log_demo.utils.exception;
import com.haoqian.log_demo.utils.result.ResultCodeEnum;
import lombok.Data;
/**
* 自定义全局异常类
*
* @author qy
*/
@Data
public class HaoqianException extends RuntimeException {
private Integer code;
/**
* 通过状态码和错误消息创建异常对象
*
* @param code
* @param message
*/
public HaoqianException(Integer code, String message) {
super(message);
this.code = code;
}
/**
* 接收枚举类型对象
*
* @param resultCodeEnum
*/
public HaoqianException(ResultCodeEnum resultCodeEnum) {
super(resultCodeEnum.getMessage());
this.code = resultCodeEnum.getCode();
}
@Override
public String toString() {
return "HaoqianException{" +
"code=" + code +
", message=" + this.getMessage() +
'}';
}
}
第二步:自定义全局异常处理器
package com.haoqian.log_demo.utils.exception;
import com.haoqian.log_demo.utils.result.Result;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseBody;
@Slf4j
@ControllerAdvice
public class GlobalExceptionHandler {
/**
* 自定义异常处理
*
* @param e 异常
* @return 统一封装的响应结果
*/
@ExceptionHandler(HaoqianException.class)
@ResponseBody
public Result error(HaoqianException e) {
log.error("info:", e);
return Result.code(500).message(e.getMessage());
}
/**
* 统一异常处理
*
* @param e 异常
* @return 统一封装的响应结果
*/
@ExceptionHandler(Exception.class)
@ResponseBody
public Result error(Exception e) {
log.error("info:", e);
return Result.code(500).message(e.getMessage());
}
}
2 测试
package com.haoqian.log_demo.controller;
import com.haoqian.log_demo.service.EmployeeService;
import com.haoqian.log_demo.utils.interceptor.TraceLog;
import com.haoqian.log_demo.utils.result.Result;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RestController;
@RestController
public class EmployeeController {
private final Logger log = LoggerFactory.getLogger(this.getClass());
@GetMapping("testCustomException/{num}")
@TraceLog
public Result testCustomException(@PathVariable("num") int num) {
int a = 10 / num;
return Result.success().data(a);
}
}
可以看到上述代码并没有使用 try…catch 捕获并处理异常,但却实现了 统一的异常捕获处理,并可以 返回自定义响应结果