springboot 自定义错误页面
Spring Boot 默认使用嵌入式 Tomcat,默认没有页面来处理404等常见错误。因此,为了给用户最佳的使用体验,404等常见错误需要我们自定义页面来处理。
在 springboot 2.0 之前用
org.springframework.boot.context.embedded.EmbeddedServletContainerCustomizer
类来实现该功能。
使用 Java7 内部类的实现:
@Bean
public EmbeddedServletContainerCustomizer containerCustomizer() {
    return new EmbeddedServletContainerCustomizer() {
        @Override
        public void customize(ConfigurableEmbeddedServletContainer container) {
            ErrorPage error401Page = new ErrorPage(HttpStatus.UNAUTHORIZED, "/401.html");
            ErrorPage error404Page = new ErrorPage(HttpStatus.NOT_FOUND, "/404.html");
            ErrorPage error500Page = new ErrorPage(HttpStatus.INTERNAL_SERVER_ERROR, "/500.html");
            container.addErrorPages(error401Page, error404Page, error500Page);
        }
    };
}Java8 的 lambda 表达式写法:
@Bean
public EmbeddedServletContainerCustomizer containerCustomizer() {
   return (container -> {
        ErrorPage error401Page = new ErrorPage(HttpStatus.UNAUTHORIZED, "/401.html");
        ErrorPage error404Page = new ErrorPage(HttpStatus.NOT_FOUND, "/404.html");
        ErrorPage error500Page = new ErrorPage(HttpStatus.INTERNAL_SERVER_ERROR, "/500.html");
        container.addErrorPages(error401Page, error404Page, error500Page);
   });
}在代码中创建了三个 ErrorPage 实例来处理三个通用的 HTTP 错误状态码,并将他们添加到 container 当中。ErrorPage 类是一个封装了错误信息的类,它可以在 Jetty 和 Tomcat 环境下使用。
错误页面需要放在项目static内容目录下,它的默认位置是:src/main/resources/static,如下图所示:

在Spring Boot2.0以上配置嵌入式Servlet容器时EmbeddedServletContainerCustomizer类不存在,被WebServerFactoryCustomizer替代
使用WebServerFactoryCustomizer接口替换EmbeddedServletContainerCustomizer 组件完成对嵌入式Servlet容器的配置,示例代码如下:
@Bean
public WebServerFactoryCustomizer webServerFactoryCustomizer() { 
  return (container -> {
      ErrorPage error401Page = new ErrorPage(HttpStatus.UNAUTHORIZED, "/error/401.html");
      ErrorPage error404Page = new ErrorPage(HttpStatus.NOT_FOUND, "/error/404.html");
      ErrorPage error500Page = new ErrorPage(HttpStatus.INTERNAL_SERVER_ERROR, "/error/500.html");
      container.addErrorPages(error401Page, error404Page, error500Page);
  });
 }在 WebServerFactoryCustomizer 接口中使用 ConfigurableWebServerFactory 对象实现对 customize() 方法的转换,从而实现对嵌入式 servlet 容器的配置。
附录
springboot 1.x
import org.apache.catalina.connector.Connector;
import org.apache.coyote.ProtocolHandler;
import org.apache.coyote.http11.Http11NioProtocol;
import org.apache.tomcat.util.threads.ThreadPoolExecutor;
import org.springframework.boot.context.embedded.ConfigurableEmbeddedServletContainer;
import org.springframework.boot.context.embedded.EmbeddedServletContainerCustomizer;
import org.springframework.boot.context.embedded.tomcat.TomcatConnectorCustomizer;
import org.springframework.boot.context.embedded.tomcat.TomcatEmbeddedServletContainerFactory;
import org.springframework.boot.web.servlet.ErrorPage;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.HttpStatus;
import org.springframework.stereotype.Component;
@Component
public class EmbeddedTomcatConfig implements EmbeddedServletContainerCustomizer{
    @Override
    public void customize(ConfigurableEmbeddedServletContainer container) {
        TomcatEmbeddedServletContainerFactory factory = (TomcatEmbeddedServletContainerFactory)container;
        factory.addConnectorCustomizers(new TomcatConnectorCustomizer() {
            @Override
            public void customize(Connector connector) {
                Http11NioProtocol protocol = (Http11NioProtocol) connector.getProtocolHandler();
                protocol.setMaxConnections(200);
                protocol.setMaxThreads(200);
                protocol.setSelectorTimeout(3000);
                protocol.setSessionTimeout(3000);
                protocol.setConnectionTimeout(3000);
            }
        });
    }
}通过实现org.springframework.boot.context.embedded.EmbeddedServletContainerCustomizer的customize方法来实现自定义
springboot 2.x
import org.apache.catalina.connector.Connector;
import org.apache.coyote.ProtocolHandler;
import org.apache.coyote.http11.Http11NioProtocol;
import org.apache.tomcat.util.threads.ThreadPoolExecutor;
import org.springframework.boot.web.embedded.tomcat.TomcatConnectorCustomizer;
import org.springframework.boot.web.embedded.tomcat.TomcatServletWebServerFactory;
import org.springframework.boot.web.server.WebServerFactoryCustomizer;
import org.springframework.boot.web.servlet.server.ConfigurableServletWebServerFactory;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.Ordered;
import org.springframework.stereotype.Component;
@Component
public class EmbeddedTomcatConfig implements WebServerFactoryCustomizer<ConfigurableServletWebServerFactory> {
    @Override
    public void customize(ConfigurableServletWebServerFactory factory) {
      ((TomcatServletWebServerFactory)factory).addConnectorCustomizers(new TomcatConnectorCustomizer() {
            @Override
            public void customize(Connector connector) {
                Http11NioProtocol protocol = (Http11NioProtocol) connector.getProtocolHandler();
                protocol.setMaxConnections(200);
                protocol.setMaxThreads(200);
                protocol.setSelectorTimeout(3000);
                protocol.setSessionTimeout(3000);
                protocol.setConnectionTimeout(3000);
            }
        });
    }
}在2.x版本改为实现org.springframework.boot.web.server.WebServerFactoryCustomizer接口的customize方法
springboot1.x 相关类如下:
org.springframework.boot.context.embedded.ConfigurableEmbeddedServletContainer
org.springframework.boot.context.embedded.EmbeddedServletContainerCustomizer
org.springframework.boot.context.embedded.tomcat.TomcatConnectorCustomizer
org.springframework.boot.context.embedded.tomcat.TomcatEmbeddedServletContainerFactoryspringboot2.x 相关类如下:
org.springframework.boot.web.servlet.server.ConfigurableServletWebServerFactory
org.springframework.boot.web.server.WebServerFactoryCustomizer
org.springframework.boot.web.embedded.tomcat.TomcatConnectorCustomizer
org.springframework.boot.web.embedded.tomcat.TomcatServletWebServerFactory

喜欢,在看
