springBoot中全局异常处理,针对ajax响应(包括Rest接口请求)和页面请求响应

完善的异常处理可以让客户端有一个良好的体验,并且有利于定位出错原因,帮助更好的解决问题。
SpringBoot 内置了一个 /error 处理,当抛出异常之后,会被转到这个映射进行处理, 就是常见的 Whitelable Error Page
在这里插入图片描述
另外一种就是使用ajax请求,SpringBoot会返回如下的Json格式字符串信息‘’
在这里插入图片描述
原理很简单,SpringBoot默认提供了程序出错的结果映射路径/error。这个/error请求是会在BasicErrorController中进行处理,其内部是通过判断请求头中的Accept的内容是否是text/html来区分是客户端浏览器(浏览器通常默认自动发送请求头内容Accept:text/html)还是客户端接口的调用,以此来决定返回视图还是JSON消息的内容,如下图是BasicErrorController的底层源码(在idea中三次按shift键将进入底层源码)
在这里插入图片描述
在这里插入图片描述

定义一个简单的error.html页面
<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org" >
<head>
    <meta charset="UTF-8"/>
    <title>error</title>
</head>
<body>
server error
<p th:text="${errorMessage}"/>
</body>
</html>
定义一个全局的GlobalRestExceptionHandler类来进行处理ajax响应和页面请求响应
/**
 * @Description: 全局异常处理,针对ajax响应和页面请求响应
 */
@RestControllerAdvice
public class GlobalRestExceptionHandler {

    private Logger logger = LoggerFactory.getLogger(getClass());

    @ExceptionHandler(Exception.class)
    public Object exception(HttpServletRequest reqest, HttpServletResponse response,HandlerMethod handlerMethod, Exception exception) {

        Method m = handlerMethod.getMethod();
        Class<?> clazz = handlerMethod.getBeanType();
        //判断访问的url是否为rest接口请求
        boolean isRestReq = (m.getAnnotation(ResponseBody.class)!=null
                ||clazz.getAnnotation(ResponseBody.class)!=null
                ||clazz.getAnnotation(RestController.class)!=null);
        //判断访问的url是否为ajax请求
        boolean isAjax = isAjax(reqest);
        if (isAjax||isRestReq) {
            logger.error("global exception", exception);
            if (exception instanceof VeException) {
                return ResultInfo.fail(VeErrorCode.UNKNOWN_EXCEPTION, exception.getMessage());
            }
            return ResultInfo.fail(VeErrorCode.UNKNOWN_EXCEPTION);
        } else {
            logger.error("界面请求异常", exception);
            ModelAndView mv = new ModelAndView();
            if (exception instanceof VeException) {
                mv.addObject("errorMessage", exception.getMessage());
                mv.setViewName("error");
                return mv;
            }
            mv.addObject("errorMessage", "");
            mv.setViewName("error");
            return mv;
        }
    }

    /**
     * 判断网络请求是否为ajax
     *
     * @param req
     * @return
     */
    private boolean isAjax(HttpServletRequest req) {
        String contentTypeHeader = req.getHeader("Content-Type");
        String acceptHeader = req.getHeader("Accept");
        String xRequestedWith = req.getHeader("X-Requested-With");
        return (contentTypeHeader != null && contentTypeHeader.contains("application/json"))
                || (acceptHeader != null && acceptHeader.contains("application/json"))
                || "XMLHttpRequest".equalsIgnoreCase(xRequestedWith);
    }
}
VeException 中的内容
**
 * 全局异常
 */
public class VeException extends RuntimeException {
    private String code;
    private String message;

    public VeException(VeErrorCode errorCode) {
        super(errorCode.getCode());
        this.code = errorCode.getCode();
        this.message = errorCode.getMessage();
    }

    public String getCode() {
        return code;
    }

    @Override
    public String getMessage() {
        return message;
    }
}
VeErrorCode中的内容
public enum VeErrorCode {
 UNKNOWN_EXCEPTION("unknown_exception","系统内部错误");
   private String code;
    private String message;


    private VeErrorCode(String code, String message) {
        this.code = code;
        this.message = message;
    }

    public String getCode() {
        return code;
    }

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

    public String getMessage() {
        return message;
    }

    public void setMessage(String message) {
        this.message = message;
    }
}

测试:将会出现两种

ajax请求响应在这里插入图片描述

在这里插入图片描述

页面请求响应

在这里插入图片描述
在这里插入图片描述
测试成功
版权声明:转载请标明博客地址,谢谢!

  • 2
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值