Spring框架错误页过滤器
springboot提供了一个ErrorPageFilter,用来处理当程序发生错误时如何展现错误,话不多说请看代码
private void doFilter(HttpServletRequest request, HttpServletResponse response,
FilterChain chain) throws IOException, ServletException {
ErrorWrapperResponse wrapped = new ErrorWrapperResponse(response);
try {
chain.doFilter(request, wrapped);
if (wrapped.hasErrorToSend()) {
// 重点关注此方法
handleErrorStatus(request, response, wrapped.getStatus(),
wrapped.getMessage());
response.flushBuffer();
}
else if (!request.isAsyncStarted() && !response.isCommitted()) {
response.flushBuffer();
}
}
catch (Throwable ex) {
Throwable exceptionToHandle = ex;
if (ex instanceof NestedServletException) {
exceptionToHandle = ((NestedServletException) ex).getRootCause();
}
handleException(request, response, wrapped, exceptionToHandle);
response.flushBuffer();
}
}private void handleErrorStatus(HttpServletRequest request,
HttpServletResponse response, int status, String message)
throws ServletException, IOException {
if (response.isCommitted()) {
handleCommittedResponse(request, null);
return;
}
// 获取错误页,来关注下这个属性this.statuses,就是一个map,而错误页就是从这属性中获取,那此属性的内容是什么时候添加进去的呢
String errorPath = getErrorPath(this.statuses, status);
if (errorPath == null) {
response.sendError(status, message);
return;
}
response.setStatus(status);
setErrorAttributes(request, status, message);
// 拿到错误页地址后,通过服务器重定向的方式跳转到错误页面
request.getRequestDispatcher(errorPath).forward(request, response);
}ErrorPageFilter implements Filter, ErrorPageRegistry,此类实现了ErrorPageRegistry接口,接口内方法如下,我们可以看到这个入参errorPages便是错误页集合,然后把所有错误页put到statuses属性内,但是此方法入参从何而来呢?
@Override
public void addErrorPages(ErrorPage... errorPages) {
for (ErrorPage errorPage : errorPages) {
if (errorPage.isGlobal()) {
this.global = errorPage.getPath();
}
else if (errorPage.getStatus() != null) {
this.statuses.put(errorPage.getStatus().value(), errorPage.getPath());
}
else {
this.exceptions.put(errorPage.getException(), errorPage.getPath());
}
}
}通过源码分析,发现此接口,只要实现此接口并生成bean交给spring,便可以往ErrorPageRegistry添加你自己的错误页了。
public interface ErrorPageRegistrar {
/**
* Register pages as required with the given registry.
* @param registry the error page registry
*/
void registerErrorPages(ErrorPageRegistry registry);
}看个例子吧,这样就可以了,是不是很简单。
@Component
public class MyErrorPage implements ErrorPageRegistrar {
@Override
public void registerErrorPages(ErrorPageRegistry registry) {
ErrorPage error404Page = new ErrorPage(HttpStatus.NOT_FOUND, "/WEB-INF/errorpage/404.html");
ErrorPage error405Page = new ErrorPage(HttpStatus.METHOD_NOT_ALLOWED, "/WEB-INF/errorpage/405.html");
ErrorPage error500Page = new ErrorPage(HttpStatus.INTERNAL_SERVER_ERROR, "/WEB-INF/errorpage/500.html");
registry.addErrorPages(error404Page, error405Page, error500Page);
}
}版权声明:本文为lynn349x原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。