欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

springboot?ErrorPageFilter的實際應(yīng)用詳解

 更新時間:2022年01月27日 14:50:56   作者:零零落落。  
這篇文章主要介紹了springboot?ErrorPageFilter的實際應(yīng)用詳解,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教

ErrorPageFilter的實際應(yīng)用

Spring框架錯誤頁過濾器

springboot提供了一個ErrorPageFilter,用來處理當程序發(fā)生錯誤時如何展現(xiàn)錯誤,話不多說請看代碼

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()) {
? ? ? ? ? ? // 重點關(guān)注此方法
? ? ? ? ? ? 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;
? ? }
? ? // 獲取錯誤頁,來關(guān)注下這個屬性this.statuses,就是一個map,而錯誤頁就是從這屬性中獲取,那此屬性的內(nèi)容是什么時候添加進去的呢
? ? String errorPath = getErrorPath(this.statuses, status);
? ? if (errorPath == null) {
? ? ? ? response.sendError(status, message);
? ? ? ? return;
? ? }
? ? response.setStatus(status);
? ? setErrorAttributes(request, status, message);
? ? // 拿到錯誤頁地址后,通過服務(wù)器重定向的方式跳轉(zhuǎn)到錯誤頁面
? ? request.getRequestDispatcher(errorPath).forward(request, response);
}

ErrorPageFilter implements Filter, ErrorPageRegistry,此類實現(xiàn)了ErrorPageRegistry接口,接口內(nèi)方法如下,我們可以看到這個入?yún)rrorPages便是錯誤頁集合,然后把所有錯誤頁put到statuses屬性內(nèi),但是此方法入?yún)暮味鴣砟兀?/p>

@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());
? ? ? ? }
? ? }
}

通過源碼分析,發(fā)現(xiàn)此接口,只要實現(xiàn)此接口并生成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項目出現(xiàn)ErrorPageFilter異常

今天用springboot(2.2.12.RELEASE)+beetl模板的時候,由于某個模板找不到,

系統(tǒng)一直出現(xiàn)報錯日子

[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

看了網(wǎng)上的一些解決方法,大體上都是重寫ErrorPageFilter,然后在FilterRegistrationBean中設(shè)置 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;
? ? }

按照這個方法,我做了多次嘗試,系統(tǒng)直接報錯說errorPageFilter沖突了,原來是

ErrorPageFilterConfiguration.java中已經(jīng)定義了這么一個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;
    }
}

最后我的解決方式是在啟動類中設(shè)置:

@SpringBootApplication
public class App extends SpringBootServletInitializer {
public App() {
? ? super();
? ? //下面設(shè)置為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);
}

問題解決。 

以上為個人經(jīng)驗,希望能給大家一個參考,也希望大家多多支持腳本之家。

相關(guān)文章

最新評論