Spring-boot ErrorPage不能与独立的Tomcat一起使用

我仍然在努力让Spring-boot错误页面完全在一个带有部署WAR文件的独立tomcat中运行。

我有一个配置类如下:

@Configuration @ComponentScan @EnableAutoConfiguration(exclude = [ GroovyTemplateAutoConfiguration, SecurityAutoConfiguration, ErrorMvcAutoConfiguration, JmxAutoConfiguration ] ) class Application extends SpringBootServletInitializer { @Override protected SpringApplicationBuilder configure( SpringApplicationBuilder application ) { application.sources( Application ) } 

并且我的error handling配置如下:

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

这个信息似乎得到了使用,但并不像我期望的那样 – 如果我只是去一个不存在的URL然后我得到tomcat默认的404页面 – 但是,Spring似乎正在返回我的ErrorPage路径,如Tomcat页面看起来像这样:

 HTTP Status 404 - //errors/404 type Status report message //errors/404 description The requested resource is not available. Apache Tomcat/7.0.54 

如果我更改我的错误配置并使用不同的路径,那么该路径将作为404消息传递 – 有人知道我错过了什么吗? 我希望消息只是“未找到”和用于解析视图/控制器以呈现错误页面的路径/ errors / 404。


更新我在我的Web配置中将错误路径映射为标准视图控制器:

 @Configuration @EnableWebMvc class WebMvcConfiguration extends WebMvcConfigurerAdapter { /** * Register static views that dont need controller calls - map URLs direct to views */ @Override public void addViewControllers(ViewControllerRegistry registry) { registry.addViewController("/errors/404").setViewName("errors/404") registry.addViewController("/errors/500").setViewName("errors/500") } 

另外,如果我直接进入浏览器中的错误路径 – / errors / 404 – 那么我会得到我期望的错误页面。


更新2

我创建了一个虚拟的Spring Boot Web应用程序,它具有自动error handlingfunction,并部署到我在Eclipse中运行的tomcat,并且whitelabel错误页面正确显示。 然后我将它部署到我的开发服务器tomcat上,whitelabel错误页面停止工作(我看到默认的tomcat 404页面)。

我的web.xml在两者中是相同的(将web.xml从eclipse复制到dev服务器),server.xml在下面(实际上与eclipse版本基本相同)

                        

此外:

  1. 如果我直接导​​航到/ error我看到whitelabel页面,所以端点工作正常
  2. 如果我在webroot中创建一个名为“error”的文件,则会获取并显示该文件。 因此,似乎应用程序正在尝试正确地重新路由我的404,但由于某种原因只是寻找“错误”文件,而不是应用程序中的“错误”端点

更新3

我进一步调查了,即使我在本地,干净的tomcat安装上使用完全相同的server.xml和web.xml,它仍然在本地工作。

我还看到请求的RequestDispatch似乎存在问题。

如果我在我的开发服务器上运行以下代码(例如,从控制器运行),它不起作用:

 request.getRequestDispatcher("/errors/404").forward(request,response); 

但以下是:

 servletContext.getRequestDispatcher("/errors/404").forward(request,response); 

(其中请求和响应是HttpServletRequest / Response,而servletContext是一个自动assembly的ServletContext对象)

以上两个示例都在干净的本地tomcat安装上正常工作 – 任何想法可能会导致请求链接的RequestDispatcher出现问题,而ServletContext RequestDispatcher仍然有效吗? ErrorPageFilter使用请求链接的RequestDispatcher,因此遇到此问题。

最后它是因为在tomcat appBase中创建了一个ROOT目录(这是作为WAR部署过程的一部分而创建的) – 看起来这样会导致两个ROOT上下文混淆(部署了WAR)作为ROOT战争)。

修复tomcat设置,使其只有预期的WAR文件开始工作。