搭建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");
}
}
}
