统一处理异常的实现

统一处理异常

服务端分为三层架构:表现层、业务层和数据层。

浏览器发送的请求一律发送给表现层,表现层调用业务层,业务层调用数据层(假如数据层出现异常,会抛给调用者业务层,业务层再往上抛会抛给表现层,就其实表现层是冲在最前方的,所以无论是数据层还是业务层的异常都会汇集到表现层)。

我们统一地对表现层捕获异常,就能处理所有的异常。

  1. SpringBoot提供了一些现成的方案,在项目的某一个特定的路径下加上对应特定错误状态的页面,项目在发现特定错误就会跳转到对应的页面(特定路径为:resources目录下的templates目录下的名为error的目录,且一定要命名为error,页面的名字一定是错误状态码)。
  2. 当出现服务端错误,我们可能会需要记录一些日志好进行相应的处理,Spring也有统一处理的方式。
    @ControllerAdvice:用于修饰类,表示该类是Controller的全局配置类,在此类中,可以对Controller进行如下三种全局配置,即异常处理方案、绑定数据方案、绑定参数方案。
    @ExceptionHandler:用于修饰方法,该方法会在Controller出现异常后被调用,用于处理捕获到的异常。
    @ModelAttribute:用于修饰方法,该方法会在Controller方法执行前被调用,用于为Model对象绑定参数。
    @DataBinder:用于修饰方法,该方法会在Controller方法执行前被调用,用于绑定参数的转换器。

代码实现:

  1. 先写好一个错误的请求,Controller发生异常后,记录完日志之后需要重定向到错误页面:

    	// @RequestMapping(path = "/error",method = RequestMethod.GET)
        @GetMapping("/error")
        public String getErrorPage() {
            return "/error/500";
        }
    
  2. 新建一个通知类ExceptionAdvice:

    @ControllerAdvice(annotations = Controller.class)
    public class ExceptionAdvice {
    
        private static final Logger logger = LoggerFactory.getLogger(ExceptionAdvice.class);
    
        @ExceptionHandler({Exception.class})
        // 方法名随便取,常用的参数为三个(Exception,HttpServletRequest,HttpServletResponse)
        // 当这个方法被调用就说明Controller肯定出现异常了
        public void handleException(Exception e, HttpServletRequest request, HttpServletResponse response) throws IOException {
            logger.error("服务器发生异常:" + e.getMessage());
            // 栈的详细信息
            for (StackTraceElement element : e.getStackTrace()) {
                logger.error(element.toString());
            }
    
            // 记录完日志之后需要给浏览器一个响应,需要重定向到错误页面
            String xRequestedWith = request.getHeader("x-requested-with");
            if("XMLHttpRequest".equals(xRequestedWith)) {
                // 则为异步请求(此处采用向浏览器返回的是一个普通字符串,浏览器得到后需要人为的转为json格式)
                response.setContentType("application/plain;charset=utf-8");
                PrintWriter writer = response.getWriter();
                writer.write(CommunityUtil.getJSONString(1,"服务器异常"));
            } else {
                // 则为普通请求
                response.sendRedirect(request.getContextPath() + "/error");
            }
        }
    }
    

使用这个组件的好处:

我们不需要对任何一个Controller做处理,不用在任何一个Controller上加代码就能解决问题。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值