Filter中抛出异常@RestControllerAdvice注解无法捕获的问题

搭建springboot+shiro+jwt的时候,发现RestControllerAdvice全局异常处理无法获取filter中的异常

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

原因

请求进来 会按照 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接口就行了

方法一

新建MyErrorController并继承BasicErrorController

import cn.hutool.core.util.ObjectUtil;
import com.iof.upms.common.result.Result;
import io.swagger.annotations.Api;
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.Map;

@RestController
@Api(value = "filter错误处理", description = "filter错误处理")
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) {
        getErrorProperties().setIncludeException(true);
        getErrorProperties().setIncludeMessage(ErrorProperties.IncludeAttribute.ALWAYS);
        getErrorProperties().setIncludeStacktrace(ErrorProperties.IncludeAttribute.ALWAYS);
        Map<String, Object> body = getErrorAttributes(request, getErrorAttributeOptions(request, MediaType.ALL));
        HttpStatus status = getStatus(request);
        //错误信息
        Object obj = body.get("message");
        //获取异常信息
        String exception = String.valueOf(body.get("exception"));
        //如果是shiro异常则返回666,否则返回500
        int code = "org.apache.shiro.authc.AuthenticationException".equals(exception) ? 666 : 500;
        return new ResponseEntity(Result.error(code, ObjectUtil.isNull(obj) ? "系统异常,请重新登录!" : String.valueOf(obj)), HttpStatus.OK);
    }
}

方法二

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;

@RestController
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");
        }
    }
}

站在巨人肩膀上摘苹果

https://www.yisu.com/zixun/541100.html

posted @ 2021-09-24 14:02  未月廿三  阅读(2762)  评论(0编辑  收藏  举报