使用 mod_jk 和 Apache httpd 时为 Tomcat 的 404 页面使用自定义错误页面

Posted

技术标签:

【中文标题】使用 mod_jk 和 Apache httpd 时为 Tomcat 的 404 页面使用自定义错误页面【英文标题】:Use custom error page for Tomcat's 404 Page when using mod_jk and Apache httpd 【发布时间】:2017-11-09 14:50:48 【问题描述】:

我们有这样的设置:

httpd <-> mod_jk (Tomcat)

httpd 被配置为将所有对 URL /app* 的请求转发到 mod_jk。 httpd 为 HTTP 错误 404、500 等配置了自定义错误页面。

如果用户输入 URL,http://hostname/non-existing-page - 然后会显示 httpd 的自定义 404 错误页面。

如果用户输入 URL,http://hostname/app-blabblah - 则显示 Tomcat 的 404 错误页面。如果 /app/non-existentpage 类似,托管在 /app 的应用程序可以处理 404 错误。但是 context /app-blablah 不会解析到 Tomcat 上的任何 war 文件,因此会导致 Tomcat 的 404 错误页面。

我们使用的是精简版的Tomcat,它的webapps文件夹只有app.war

我被要求不要显示 Tomcat 404 错误页面,因为它表明应用程序托管在 Tomcat 上并且还显示 Tomcat 的版本。

如果有人可以告诉我如何:

    当 Tomcat 必须处理表示不存在上下文的 URL 时,为 Tomcat 添加自定义 404 错误页面。 或者配置 httpd,如果它看到 Tomcat 返回 404 错误,它会呈现自己的自定义 404 错误页面。

PS:我不能随意将 /app/* 指向 mod_jk,因为我们有时会出于调试目的部署其他以 app 开头的战争——例如应用程序调试战争。

更新:我将 mod_jk workers.properties 更改为仅将 /app/* 转发到 Tomcat。

【问题讨论】:

请查看此链接***.com/questions/13914575/… 和此链接***.com/questions/15987212/… 干杯 @Devdas 感谢您的链接。正如我在帖子中提到的,“app”上下文中的任何错误 URL 都会显示我们的自定义错误页面。但是如果上下文名称本身是错误的,比如“app-blahblah”,那么,请求将不会到达“app.war”,并且将由 Tomcat 处理 - 当 Tomcat 找不到任何匹配的上下文时 - 它会报告 404 页面 -一个标准的 Tomcat 404 错误页面。我需要将此错误页面修改为自定义页面。 您只能使用“mod_proxy”来做到这一点,只需摆脱 mod_jk 并使用带有 ProxyErrorOverride 指令的 mod_proxy。 你能添加一个只显示错误的ROOT.war吗? 【参考方案1】:

如果您已将 tomcat 与 apache 集成并为其使用了 mod_jk,则使用以下步骤处理 404 和 401 自定义错误页面。

所有步骤都在下面的链接中提及。

https://devopstech2020.blogspot.com/2021/07/use-custom-error-page-for-tomcats-404.html

【讨论】:

请在您的答案中至少引用链接中提供的解决方案的基本部分。由于链接的帖子使用图像,您必须输入一两行文本(例如use_server_errors)。 我已经在链接 Add use_server_errors=400,500 中添加了这部分。但是谢谢,我会更多地探索它。【参考方案2】:

回答你的问题:

    为 Tomcat 添加自定义 404 错误页面,当它必须处理 URL 时 表示不存在的上下文。

并尊重您的初始约束:

我不能只将 /app/* 指向 mod_jk,因为我们有时 部署以应用程序开头的其他战争以进行调试 - 用于 例如app-debug.war.

最简单的解决方案是使用 ROOT webapp 文件夹。但是,为了尊重您保持 webapps 文件夹简约的其他条件,您不必在 ROOT webapp 文件夹中保留任何内容,但您的自定义错误页面

使用此配置,您只需添加 $CATALINA_BASE/conf/web.xml

<error-page>
  <error-code>404</error-code>
  <location>/general-error.html</location>
</error-page>

或任何最适合您想要的东西。 (在这里,您可以使用与您的 app.war 相同的错误自定义页面,最终用户不会看到差异)。


结果是:

情况一:http://hostname/non-existing-page

将显示httpd错误自定义页面

情况2:http://hostname/app/non-existing-page

将显示您的应用程序 app.war 的错误自定义页面。 (使用$CATALINA_BASE/conf/web.xml,然后使用$CATALINA_BASE/webapps/app/WEB-INF/web.xml)

情况3:http://hostname/app-dummy-url

将显示您的 ROOT 文件夹的 Tomcat 错误自定义页面。 (仅使用 $CATALINA_BASE/conf/web.xml)。

在您编辑时,您删除了约束,现在可以:

chang(e) mod_jk workers.properties 仅将 /app/* 转发到 Tomcat。

在此配置中,您将获得与您想要的替代方案相同的结果:

    或者配置 httpd,如果它看到 Tomcat 返回 404 错误,它会呈现自己的自定义 404 错误页面。

但是,如果您仍想使用问题中提到的调试 war 文件 (app-debug.war),则每次都需要修改 httpd 配置(worker.properties 和可能还有您的 VirtualHosts)和/或者让这些文件中的调试配置。由于它似乎不适合生产环境,因此在 Tomcat 中使用仅包含自定义页面的文件夹 ROOT 似乎是 IMO 的最佳解决方案。

【讨论】:

感谢您的回答。我们的产品有自定义脚本来启动 Tomcat,这似乎会清理所有目录的 Webapps 目录作为重启的一部分。我找到了对 ErrorReportValve 的引用,它可以让我在 Tomcat 错误页面中隐藏服务器信息,但我们的 Tomcat 版本比将标志添加到此类的版本更旧。我尝试修改全局 web.xml,它位于 Tomcat 的 conf 文件夹中以添加 ErrorPage 指令 - 它导致浏览器上出现空白内容 - 我希望它可以重定向到 httpd 的错误页面 /error/http404.html。跨度> 你的 Tomcat 版本是多少?我只是意识到它没有在任何地方提及/没有人问。 (另外,哪个 Apache 版本?) 7.0.53是Tomcat版本 使用自定义 ErrorReportValve 来显示错误页面应该适用于 Tomcat 7。(请参阅 this link)。附带说明一下,当您修改 $CATALIBA_BASE/conf/ 文件夹的 web.xml 时(正如我在回答中建议的那样),它会在 $CATALINA_BASE/webapps/ROOT 中查找您的 custom-error-url.html 页面。所以你得到了一个空白页,因为这里没有找到任何东西。如果您无法修改重启脚本(这会清除您的 webapps 文件夹,包括 ROOT),那么使用自定义 Valve 可能确实是您的解决方案。

以上是关于使用 mod_jk 和 Apache httpd 时为 Tomcat 的 404 页面使用自定义错误页面的主要内容,如果未能解决你的问题,请参考以下文章

通过centos 8上的mod_jk将apache httpd重定向到tomcat

无法在 HTTPD.CONF 文件中配置 mod_JK 以进行负载平衡

会话混合 - apache httpd 与 mod_jk、tomcat、spring security - 提供其他用户的数据

Apache+Tomcat+mod_jk配置教程

安装 mod_jk.so 后配置 http 未运行

mod_jk utf-8 字符集设置