通常的Spring全局异常处理并不能处理Filter中的异常。
Filters happens before controllers are even resolved
so exceptions thrown from filters can't be caught by a Controller Advice.
Filters are a part of the servlet and not really the MVC stack.
How to manage exceptions thrown in filters in Spring?中有不同的解答版本。
我采取的解决办法是:在web.xml中配置error页面:
<error-page>
<error-code>500</error-code>
<location>/500</location>
</error-page>
//或者,两种方式都可以
<error-page>
<exception-type>java.lang.Throwable</exception-type>
<location>/500</location>
</error-page>
然后,创建专门处理错误的Controller:
@Controller
public class ErrorController {
@RequestMapping("/404")
public void unmappedRequest(HttpServletRequest request, HttpServletResponse response) {
String uri = request.getRequestURI();
response.setStatus(HttpServletResponse.SC_OK);
throw new UnknownResourceException("你确定接口地址写对了?我还没写这个接口呢");
}
@RequestMapping("/500")
public void handlerFilterError(HttpServletRequest request) {
Throwable t = (Throwable) request.getAttribute("javax.servlet.error.exception");
throw new SystemException(t.getMessage());
}
}
之后,就可以在全局处理异常地方处理了,并且异常信息不回丢失。
我这里采用的是@ControllerAdvice的方式进行的全局异常处理。
@ControllerAdvice
public class GlobalExceptionHandler {
private static final Logger logger = LoggerFactory.getLogger(GlobalExceptionHandler.class);
.....
.....
/**
* 处理系统异常
*
* @param e
* @return
*/
@ExceptionHandler(SystemException.class)
@ResponseBody
JSONObject handleSystemException(SystemException e) {
logger.error(e.getMessage(), e);
return Result.fail("系统异常:" + e.getMessage());
}
.......
}