RestControllerAdvice无法捕获filter中抛出的异常问题

发布时间:2021-07-07 16:55:55 作者:chen
来源:亿速云 阅读:2355

本篇内容主要讲解“RestControllerAdvice无法捕获filter中抛出的异常问题”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“RestControllerAdvice无法捕获filter中抛出的异常问题”吧!

搭建springboot+shiro+jwt的时候,发现RestControllerAdvice全局异常处理无法获取filter中的异常,然后找到这个老哥的文章,确实解决了我的问题:

记一次RestControllerAdvice无法拦截Filter内抛出异常

做个备忘也贴一下原文的内容

今天有同事用到Shiro使用JWT的时候在Filter里做身份验证,然后在里面catch捕获并抛出了自定义异常。我们这边是用的RestControllerAdvice做统一异常处理,然后这个异常并没有被RestControllerAdvice所拦截到

原因
请求进来 会按照 filter -> interceptor -> controllerAdvice -> aspect -> controller的顺序调用

当controller返回异常 也会按照controller -> aspect -> controllerAdvice -> interceptor -> filter来依次抛出

这种Filter发生的404、405、500错误都会到Spring默认的异常处理。如果你在配置文件配置了server.error.path的话,就会使用你配置的异常处理地址,如果没有就会使用你配置的error.path路径地址,如果还是没有,默认使用/error来作为发生异常的处理地址。如果想要替换默认的非Controller异常处理直接实现Spring提供的ErrorController接口就行了

解决方案
新建一个ErrorControllerImpl 实现ErrorController 把ErrorPath 指向error 再写一个方法把Error抛出 然后Controller全局统一异常处理RestControllerAdvice就能捕获到异常了

import org.springframework.boot.web.servlet.error.ErrorController;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;

import javax.servlet.http.HttpServletRequest;

/**
 * @author Joe
 * createTime 2020/07/27 14:39
 * mail joe-code@foxmail.com
 */
@Controller
public class ErrorControllerImpl implements ErrorController {

    @Override
    public String getErrorPath() {
        return "/error";
    }

    @RequestMapping("/error")
  	
    public void handleError(HttpServletRequest request) throws Throwable {
        if (request.getAttribute("javax.servlet.error.exception") != null) {
            throw (Throwable) request.getAttribute("javax.servlet.error.exception");
        }
    }
}

最后,其实也是来自于:参考stackoverflow链接 https://stackoverflow.com/questions/34595605/how-to-manage-exceptions-thrown-in-filters-in-spring

 第二种方式也能解决,也记录一下:

package com.hs.demo.exception;

import org.springframework.boot.autoconfigure.web.ErrorProperties;
import org.springframework.boot.autoconfigure.web.servlet.error.BasicErrorController;
import org.springframework.boot.web.servlet.error.DefaultErrorAttributes;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.servlet.http.HttpServletRequest;
import java.util.HashMap;
import java.util.Map;

/**
 * GlobalException 全局异常处理没法处理过虑器中抛出的异常
 * 和执行顺序有关:filter -> interceptor -> controllerAdvice -> aspect -> controller
 * 当controller返回异常 也会按照controller -> aspect -> controllerAdvice -> interceptor -> filter来依次抛出
 * 注:使用ErrorControllerImpl来解决了,这个先注掉
 */
//@RestController
public class MyErrorController extends BasicErrorController {

    public MyErrorController() {
        super(new DefaultErrorAttributes(), new ErrorProperties());
    }

    @Override
    @RequestMapping(produces = {MediaType.APPLICATION_JSON_VALUE})
    public ResponseEntity<Map<String, Object>> error(HttpServletRequest request) {
        // 设置一下信息,在application.properties中配置不生效,应该是和上面的构造方法传的有关,先这么配置,待研究
        getErrorProperties().setIncludeException(true);
        getErrorProperties().setIncludeMessage(ErrorProperties.IncludeAttribute.ALWAYS);
        getErrorProperties().setIncludeStacktrace(ErrorProperties.IncludeStacktrace.ALWAYS);
        Map<String, Object> body = getErrorAttributes(request, getErrorAttributeOptions(request, MediaType.ALL));
        HttpStatus status = getStatus(request);

        Map<String, Object> map = new HashMap<String, Object>();
        map.put("code", body.get("status"));
        map.put("message", "".equals(body.get("message")) ? "系统错误" : body.get("message"));
        return new ResponseEntity<>(map, status);
    }
}

同一个请求,使用第一种方式的截图

RestControllerAdvice无法捕获filter中抛出的异常问题

使用第二种方式的截图

RestControllerAdvice无法捕获filter中抛出的异常问题

个人感觉第一种方式更好

到此,相信大家对“RestControllerAdvice无法捕获filter中抛出的异常问题”有了更深的了解,不妨来实际操作一番吧!这里是亿速云网站,更多相关内容可以进入相关频道进行查询,关注我们,继续学习!

推荐阅读:
  1. C++ 异常抛出以及捕获
  2. java中不捕获或抛出的异常

免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。

上一篇:k8s中ingress的安装方法

下一篇:C#中怎么读取资源文件

相关阅读

您好,登录后才能下订单哦!

密码登录
登录注册
其他方式登录
点击 登录注册 即表示同意《亿速云用户服务条款》