springboot接口全局异常处理

前言

记得很早之前,写过一篇springmvc全局异常处理总结springmvc异常统一处理。由于springmvc是传统的mvc框架,所以最终异常处理是在项目的配置文件中配置error异常页面,这里再和大家一起总结下springboot项目中的全局异常处理。公司的项目都是前后端分离的,所以统一异常处理是指接口的统一异常处理,返回对应的状态码,由前端或者客户端同学根据约定好的状态码做出相应的交互相应。避免直接将具体的异常堆栈直接抛给用户,下面给出具体的demo。

接口返回包装类

在日常开发中,我们通常都会给接口定义一个通用规范的响应包装类,便于前端同学解析结果响应

/**
 * @author 爱琴孩
 */
public class Response<T> {

    public static Response SUCCESS_RESPONSE = new Response(RetCode.SUCCESS.getCode(),
            RetCode.SUCCESS.getDesc());

    private String code;

    private String desc;

    private T biz;

    public Response() {
    }

    public Response(RetCode retCode) {
        this.code = retCode.getCode();
        this.desc = retCode.getDesc();
    }

    public Response(RetCode retCode, T biz) {
        this.code = retCode.getCode();
        this.desc = retCode.getDesc();
        this.biz = biz;
    }

    public Response(String code, String desc) {
        this.code = code;
        this.desc = desc;
    }

    public Response(String code, String desc, T biz) {
        this.code = code;
        this.desc = desc;
        this.biz = biz;
    }

    public String getCode() {
        return code;
    }

    public void setCode(String code) {
        this.code = code;
    }

    public String getDesc() {
        return desc;
    }

    public void setDesc(String desc) {
        this.desc = desc;
    }

    public T getBiz() {
        return biz;
    }

    public void setBiz(T biz) {
        this.biz = biz;
    }

}

通用状态码类

我们在接口中的一些参数,权限校验返回的状态码都需要在接口文档中规范清楚,在联调测试中减少提高联调效率

public class RetCode {

    public static final RetCode SUCCESS = new RetCode("000000", "success");

    public static final RetCode PARAM_ERROR = new RetCode("000001", "param is error");

    public static final RetCode ERROR = new RetCode("999999", "error");
    /**
     * 返回码
     */
    private final String code;

    /**
     * 描述
     */
    private final String desc;

    /**
     * getter method
     *
     * @return the code
     * @see RetCode#code
     */
    public String getCode() {
        return code;
    }

    /**
     * getter method
     *
     * @return the desc
     * @see RetCode#desc
     */
    public String getDesc() {
        return desc;
    }

    /**
     * @param code
     * @param desc
     */
    public RetCode(String code, String desc) {
        super();
        this.code = code;
        this.desc = desc;
    }
}

全局异常处理类

其实这里的全局异常处理和springmvc框架一样的,都是基于@ControllerAdvice和@ExceptionHandler来实现的

@ControllerAdvice
public class GlobalExceptionHandler {

    private static final Log LOGGER = LogFactory.getLog(GlobalExceptionHandler.class);
    
    //这里是一个自定义异常
    @ExceptionHandler(value = {ParameterException.class})
    @ResponseStatus(HttpStatus.INTERNAL_SERVER_ERROR)
    @ResponseBody
    public void handleServletException(HttpServletResponse response,
                         ServletException e) throws IOException {
        LOGGER.info(e, e);
        Response<Object> responseObj =
                new Response<>(RetCode.PARAM_ERROR.getCode(), RetCode.PARAM_ERROR.getDesc());
        writeEntityToHttpServletResponse(responseObj, response);
    }

    @ExceptionHandler({Exception.class})
    @ResponseStatus(HttpStatus.INTERNAL_SERVER_ERROR)
    @ResponseBody
    public void handleException(HttpServletResponse response, Exception e) 
    throws IOException {
        LOGGER.error(e, e);
        Response<Object> responseObj = new Response<>(RetCode.ERROR.getCode(),
                RetCode.ERROR.getDesc());
        writeEntityToHttpServletResponse(responseObj, response);
    }

    private void writeEntityToHttpServletResponse(Object object,
                      HttpServletResponse response) throws IOException {
        byte[] returnByte = JSON.toJSONString(object).getBytes("utf-8");
        response.addHeader("Content-Type", "application/json");
        response.setHeader("Content-Length", String.valueOf(returnByte.length));
        response.getOutputStream().write(returnByte);
        response.getOutputStream().flush();
    }

}

测试接口

    @RequestMapping(value = "/testGlobalException")
    public ResponseEntity<Response<Object>> testGlobalException() {
        log.info("invoke method testGlobalException");
        int a = 1 / 0;
        Response<Object> resp = new Response<>(RetCode.SUCCESS.getCode(),RetCode.SUCCESS.getDesc());
        return new ResponseEntity<>(resp, HttpStatus.OK);
    }

测试结果

{"code":"999999","desc":"error"}

 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

爱琴孩

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值