【问题标题】:Spring Boot - custom 404 page with standalone tomcatSpring Boot - 带有独立 tomcat 的自定义 404 页面
【发布时间】:2015-02-07 18:38:59
【问题描述】:

我正在一个独立的 tomcat 实例中运行一个 Spring Boot 应用程序,并且我试图覆盖错误页面。据我了解,Spring 提供了一个过滤器 ErrorPageFilter,它允许我像往常一样设置错误页面,以便 Springs EmbeddedServletContainerCustomizer 准确处理这种情况。

所以我在一类中有我的标准自动配置/servlet 初始化程序:

@Configuration
@ComponentScan
@EnableAutoConfiguration(exclude = [ GroovyTemplateAutoConfiguration, SecurityAutoConfiguration, ErrorMvcAutoConfiguration, JmxAutoConfiguration ] )
class Application extends SpringBootServletInitializer {

    @Override protected SpringApplicationBuilder configure( SpringApplicationBuilder application ) {
        application.sources( Application )
    }

(我使用同一个类进行自动配置和 servlet init,这就是为什么我只在 configure 方法中传递我的 Application 类)

查看SpringBootServletInitializer 的源代码,似乎只需在此处扩展该类即可添加ErrorPageFilter 类。我已经关闭了ErrorMvcAutoConfiguration - 但是再次查看该源代码,它看起来只是设置默认错误页面,而不是实际设置任何ErrorPageFilter

然后我有我的错误配置文件:

@Configuration
class ErrorConfiguration implements EmbeddedServletContainerCustomizer {

    @Override public void customize( ConfigurableEmbeddedServletContainer container ) {
        container.addErrorPages(new ErrorPage( HttpStatus.NOT_FOUND, "/errors/404" ))
    }

但是,如果我只是访问一个无效的 URL,而我 DispatcherServlet 找不到匹配项,那么我只会得到 tomcats /404.html - 而不是我的视图链接到“/errors/404”(我已映射此路径到 thymeleaf 视图模板,效果很好 - 如果我导航到 /errors/404 它显示正常)

任何想法为什么我的自定义错误页面不起作用?跟踪日志,我得到一条关于ErrorPageFilter 在应用程序启动时配置和设置正常的行,但是没有提到过滤器在请求进来时做任何事情。

【问题讨论】:

  • 文档中的示例是EmbeddedServletContainerFactory。见:docs.spring.io/spring-boot/docs/current/reference/htmlsingle/…
  • 太棒了 - 我已经搜索文档好几天了,不知道我是怎么错过的!那么我是否误解了 ErrorPageFilter 类的意义?源代码/javadoc 中的 cmets 听起来真的像是该类的唯一目的是允许在独立 WAR 部署中自定义错误页面?

标签: spring spring-mvc tomcat spring-boot


【解决方案1】:

您可以将以下代码用于旧版本的 spring boot (0.5.x)

  public class ServerCustomization extends ServerProperties {

  @Override
  public void customize(ConfigurableEmbeddedServletContainerFactory factory) {

    super.customize(factory);
    factory.addErrorPages(new ErrorPage(HttpStatus.NOT_FOUND,
            "/yourpath/error-not-found.jsp"));
    factory.addErrorPages(new ErrorPage(HttpStatus.INTERNAL_SERVER_ERROR,
            "/yourpath/error-internal.jsp"));
    factory.addErrorPages(new ErrorPage("/yourpath/error-other.jsp"));
   }
}

较新的 Spring Boot 版本 (1.X.RELEASE) 对 ServerProperties 进行了一些重构。见下文,

  public class ServerCustomization extends ServerProperties {

  @Override
  public void customize(ConfigurableEmbeddedServletContainer container) {

    super.customize(container);
    container.addErrorPages(new ErrorPage(HttpStatus.NOT_FOUND,
            "/jsp/404.jsp"));
    container.addErrorPages(new ErrorPage(HttpStatus.INTERNAL_SERVER_ERROR,
            "/jsp/500.jsp"));
    container.addErrorPages(new ErrorPage("/jsp/error.jsp"));
  }

}

然后定义一个bean来注入ServerProperies。

@Bean
public ServerProperties getServerProperties() {
    return new ServerCustomization();
}

示例项目发布在git

非常重要:如果你使用maven构建,你必须将所有的资源文件存放在src/main/resources文件夹下。否则 maven 不会将这些文件添加到最终的 jar 工件中。

【讨论】:

  • 我可能会在上面的评论中选择 Evgeni 的回答,但这看起来也是一个很好的解决方案,因此将其标记为已接受。
  • 好的,我很快就和我谈过了——这些解决方案都没有什么不同......还有其他想法吗?
  • 这个答案和你自己的尝试一样正确(ServerPropertiesEmbeddedServletContainerCustomizer),所以了解更多信息(就像一个完整的项目)会很有用。
【解决方案2】:

您可以通过实现名为 error 的视图来使用 Spring Boot 的内置错误视图,或者通过设置 error.whitelabel.enabled=false 属性将其关闭并实现您自己的。我是explained more in the docs

【讨论】:

    猜你喜欢
    • 2014-11-30
    • 1970-01-01
    • 2017-08-07
    • 2023-03-15
    • 1970-01-01
    • 2016-10-31
    • 1970-01-01
    • 2013-09-17
    • 1970-01-01
    相关资源
    最近更新 更多