Spring-Boot 异常统一处理

在项目运行中,错误的抛出是很正常的,有数据验证错误,执行错误,连接错误等等各种错误类型,而根据我们定义的 API 来看,我们需要统一的返回一个约定好的错误格式。

默认错误异常抛出

Spring-Boot 提供了一个默认的错误页面 /error

@RequestMapping("/testException")
public String testException() throws Exception {
    throw new Exception("testException");
}

显示页面如下图

统一异常处理

虽然 Spring-Boot 提供了一个异常抛出页面,但是这个页面对于调用方来说非常不友好,我们需要处理成符合我们自己应用 API 样式的返回。

全局异常处理类

我们可以在实际业务的 Controller 中仍旧使用异常抛出的形式,直接用 @ControllerAdvice 标签定义一个全局的异常处理类,使用 @ExceptionHandler 来指定方法所处理的指定异常类型,这里就可以对各种自定义异常类型进行处理。

@ControllerAdvice
public class GlobalExceptionHandler {
    @ResponseStatus(HttpStatus.OK)
    @ExceptionHandler(Exception.class)
    @ResponseBody
    public String handleException(Exception e) {
        return "操作失败";
    }
}

返回 JSON 格式的数据

添加 GlobalExceptionHandler 后在页面上会直接显示 操作失败 ,而实际上这是返回了一个字符串,如果需要返回一个错误页面,需要将 handleException 方法的返回类型改为 org.springframework.web.servlet.ModelAndView 并删除 @ResponseBody 标签,在现在的实际使用中由于前后端分离的形式,实际上多数我们只需要返回一个 JSON 格式的错误信息提示即可,所以就需要用到 @ResponseBody 标签 。

返回一个 JSON 格式如果仍旧使用字符串拼接就太蠢了,类似于 Controller 的处理,Spring-Boot 支持将对象直接序列化为 JSON 格式字符串。

public class ExeResult<T> implements Serializable {
    private static final long serialVersionUID = 8613742594819219196L;
    //请求状态
    private int code;
    //执行状态
    private boolean result;
    //信息
    private String message;
    //返回数据
    private transient T data;

    public ExeResult(int code, boolean result, String message, T data) {
        this.code = code;
        this.result = result;
        this.message = message;
        this.data = data;
    }

    public static <T> ExeResult<T> getInstance(boolean result, String message) {
        return new ExeResult(200, result, message, null);
    }
    //省略getter setter
}
@ControllerAdvice
public class GlobalExceptionHandler {
    @ResponseStatus(HttpStatus.OK)
    @ExceptionHandler(Exception.class)
    @ResponseBody
    public ExeResult handleException(Exception e) {
        return ExeResult.getInstance(false, e.getMessage());
    }
}

如上修改代码后重启,再次请求 /testException 后得到返回字符串为 {"code":200,"result":false,"message":"testException","data":null}

参考链接

Spring Boot中Web应用的统一异常处理

发表评论

发表回复

*

沙发空缺中,还不快抢~