您好,登錄后才能下訂單哦!
本篇內容主要講解“springboot ErrorPageFilter怎么應用”,感興趣的朋友不妨來看看。本文介紹的方法操作簡單快捷,實用性強。下面就讓小編來帶大家學習“springboot ErrorPageFilter怎么應用”吧!
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); } }
今天用springboot(2.2.12.RELEASE)+beetl模板的時候,由于某個模板找不到,
[http-nio-8080-exec-1] ERROR o.s.b.w.s.s.ErrorPageFilter - [handleCommittedResponse,219] - Cannot forward to error page for request [/yuantuannews/list/index_1.html] as the response has already been committed. As a result, the response may have the wrong status code. If your application is running on WebSphere Application Server you may be able to resolve this problem by setting com.ibm.ws.webcontainer.invokeFlushAfterService to false
看了網上的一些解決方法,大體上都是重寫ErrorPageFilter,然后在FilterRegistrationBean中設置 filterRegistrationBean.setEnabled(false);
@Bean public ErrorPageFilter errorPageFilter() { return new ErrorPageFilter(); } @Bean public FilterRegistrationBean disableSpringBootErrorFilter(ErrorPageFilter filter) { FilterRegistrationBean filterRegistrationBean = new FilterRegistrationBean(); filterRegistrationBean.setFilter(filter); filterRegistrationBean.setEnabled(false); return filterRegistrationBean; }
按照這個方法,我做了多次嘗試,系統直接報錯說errorPageFilter沖突了,原來是
ErrorPageFilterConfiguration.java中已經定義了這么一個bean:
// // Source code recreated from a .class file by IntelliJ IDEA // (powered by Fernflower decompiler) // package org.springframework.boot.web.servlet.support; import javax.servlet.DispatcherType; import org.springframework.boot.web.servlet.FilterRegistrationBean; import org.springframework.boot.web.servlet.ServletRegistrationBean; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; @Configuration( proxyBeanMethods = false ) class ErrorPageFilterConfiguration { ErrorPageFilterConfiguration() { } @Bean ErrorPageFilter errorPageFilter() { return new ErrorPageFilter(); } @Bean FilterRegistrationBean<ErrorPageFilter> errorPageFilterRegistration(ErrorPageFilter filter) { FilterRegistrationBean<ErrorPageFilter> registration = new FilterRegistrationBean(filter, new ServletRegistrationBean[0]); registration.setOrder(filter.getOrder()); registration.setDispatcherTypes(DispatcherType.REQUEST, new DispatcherType[]{DispatcherType.ASYNC}); return registration; } }
最后我的解決方式是在啟動類中設置:
@SpringBootApplication public class App extends SpringBootServletInitializer { public App() { super(); //下面設置為false setRegisterErrorPageFilter(false); } @Override protected SpringApplicationBuilder configure(SpringApplicationBuilder application) { return application.sources(App.class); } public static void main(String[] args) { SpringApplication.run(App.class, args); }
到此,相信大家對“springboot ErrorPageFilter怎么應用”有了更深的了解,不妨來實際操作一番吧!這里是億速云網站,更多相關內容可以進入相關頻道進行查詢,關注我們,繼續學習!
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。