Spring-boot ErrorPage 不适用于独立的 Tomcat [英] Spring-boot ErrorPage not working with standalone Tomcat

查看:49
本文介绍了Spring-boot ErrorPage 不适用于独立的 Tomcat的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我仍在努力使 Spring-boot 错误页面的内容在具有部署的 WAR 文件的独立 tomcat 中完全运行.

I am still struggling to get the Spring-boot error page stuff working completely in a standalone tomcat with deployed WAR file.

我有一个配置类如下:

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

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

还有我的错误处理配置如下:

and also have my error handling configuration as follows:

@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 页面如下所示:

This info seems to be getting used, but not as I would expect - If I just go to a non-existent URL then I get the tomcat default 404 page - however, Spring does seem to be returning my ErrorPage path, as the Tomcat page looks like this:

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 用于解析视图/控制器以呈现错误页面.

If I change my error config and use a different path, then that path gets passed through as the 404 message - Does anyone know what I have missed? I am expecting the message to just be something like "Not found" and the path /errors/404 to be used to resolve a view/controller to render the error page.

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

UPDATE I have the error path mapped as a standard view controller in my web config:

@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 - 那么我会得到我期望的错误页面.

Also, if I just go straight to the error path in the browser - /errors/404 - then I get the error page I expect.

更新 2

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

I have created a dummy Spring Boot web app with auto-error handling and deployed to my tomcat running in Eclipse and the whitelabel error page displays correctly. I then deploy it on to my development server tomcat and the whitelabel error pages stop working (I see default tomcat 404 page).

我的 web.xml 是相同的(将 web.xml 从 Eclipse 复制到开发服务器),下面是 server.xml(实际上与 Eclipse 版本基本相同)

My web.xml is the same across both (copied the web.xml from eclipse to dev server) and the server.xml is below (essentially the same as the eclipse version really)

<Server port="8005" shutdown="SHUTDOWN">
  <Listener SSLEngine="on" className="org.apache.catalina.core.AprLifecycleListener"/>
  <Listener className="org.apache.catalina.core.JasperListener"/>
  <Listener className="org.apache.catalina.core.JreMemoryLeakPreventionListener"/>
  <Listener className="org.apache.catalina.mbeans.GlobalResourcesLifecycleListener"/>
  <GlobalNamingResources>
    <Resource auth="Container" description="User database that can be updated and saved" factory="org.apache.catalina.users.MemoryUserDatabaseFactory" name="UserDatabase" pathname="conf/tomcat-users.xml" type="org.apache.catalina.UserDatabase"/>
  </GlobalNamingResources>

  <Service name="Custom">
    <Executor name="tomcatThreadPoolwr" minSpareThreads="4" maxThreads="500" namePrefix="catalina-execwr-"></Executor>
    <Connector port="8081" protocol="org.apache.coyote.http11.Http11Protocol" connectionTimeout="20000" redirectPort="8443" executor="tomcatThreadPoolwr" maxThreads="10"></Connector>
    <Connector port="9998" protocol="AJP/1.3" redirectPort="8445" maxThreads="500" tomcatAuthentication="false" connectionTimeout="21000"></Connector>
    <Engine jvmRoute="custom" name="Custom" defaultHost="localhost">
      <Realm className="org.apache.catalina.realm.LockOutRealm">
        <Realm className="org.apache.catalina.realm.UserDatabaseRealm" resourceName="UserDatabase"></Realm>
      </Realm>
      <Host name="localhost" autoDeploy="true" deployOnStartup="true"  unpackWARs="false" appBase="/tmp/dev/custom" workDir="/tmp/dev/custom/work" createDirs="true">
        <Context docBase="/tmp/dev/ROOT" path="/" reloadable="true" override="true"/>
        <Valve pattern="common" directory="/var/log/tmp" prefix="custom_access_log." className="org.apache.catalina.valves.AccessLogValve" suffix=".log" resolveHosts="false"/>
      </Host>
    </Engine>
  </Service>
</Server>

此外:

  1. 如果我直接导​​航到/error,我会看到白标页面,因此端点工作正常
  2. 如果我在 webroot 中创建一个名为error"的文件,它会被选中并显示出来.因此,应用程序似乎正在尝试正确地重新路由我的 404,但出于某种原因,它只是在寻找错误"文件,而不是应用程序中的错误"端点

<小时>

更新 3

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

I have investigated further, and even if I use the exact same server.xml and web.xml on a local, clean tomcat install it still works locally.

我也看到请求的RequestDispatch似乎有问题.

I have also seen that it appears to be a problem with the RequestDispatch for the request.

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

If I run the following code on my development server (anywhere, but from a controller for example) it doesn't work:

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

但以下是:

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

(其中请求和响应是 HttpServletRequest/Response 并且 servletContext 是一个自动装配的 ServletContext 对象)

(where request and response are HttpServletRequest/Response and servletContext is an autowired ServletContext object)

上述两个示例都可以在干净的本地 tomcat 安装上正常工作 - 有什么想法可能会导致请求链接的 RequestDispatcher 出现问题,而 ServletContext RequestDispatcher 仍然有效?ErrorPageFilter 使用请求链接的 RequestDispatcher 所以遇到了这个问题.

Both of the above example work correctly on a clean local tomcat install - any ideas what might cause problems for the request linked RequestDispatcher whilst the ServletContext RequestDispatcher still works? The ErrorPageFilter uses the request linked RequestDispatcher so hits this problem.

推荐答案

最终是因为在 tomcat appBase 中创建了一个 ROOT 目录(这是作为 WAR 部署过程的一部分创建的) - 和看起来这对两个 ROOT 上下文造成了一些混淆(WAR 被部署为 ROOT 战争).

In the end it was caused because there was a ROOT directory being created in the tomcat appBase (this was being created as part of the WAR deploy process) - and it looks like that then caused some confusion with two ROOT contexts (the WAR was deployed as a ROOT war).

修复 tomcat 设置,使其具有预期的 WAR 文件,这开始工作了.

Fixing the tomcat setup so it just had the WAR file as expected this started to work.

这篇关于Spring-boot ErrorPage 不适用于独立的 Tomcat的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆