【问题标题】:Tomcat: two context paths for one webappTomcat:一个 webapp 的两个上下文路径
【发布时间】:2020-04-29 20:16:06
【问题描述】:

问题是: 我有一个 Web 应用程序,这个 Web 应用程序部署到 $TOMCAT_HOME/webapps/XXX 目录。 我可以通过http://localhost:8080/XXX 地址联系到 但是,我也想通过http://localhost:8080/YYY 地址访问网络应用程序。 我在 server.xml 中添加了以下内容:

<Server>
    <Service>
        <Engine>
            <Host>
                .......
                <Context path="/YYY" docBase="XXX"></Context>
            </Host>
        </Engine>
    </Service>
</Server>

它有所帮助,但 Tomcat 启动了两个 Web 上下文,并导致了一些其他问题。 是否可以为一个 Web 应用创建“多个”地址?

【问题讨论】:

  • @david rabinowitz:您是否对这个问题的某个特定部分感兴趣,因此是赏金?因为如果您以这种方式进行映射,Tomcat 将使应用程序在 /XXX 和 /YYY 上都可用。
  • 你不能只做一个JSP重定向吗?所以在 tomcat/webapps/YYY/ 目录下放置一个 index.jsp 来进行重定向或转发。
  • 请问您为什么要这样做? Http 服务器代理重定向将是让它工作的最简单方法。

标签: tomcat


【解决方案1】:

Web应用程序的url如下:

PROTOCOL://DOMAIN:PORT/CONTEXT/pagename

同一个应用在两个不同地址的解决方法如下:

  1. 如果您只想在协议上有所不同(比如说在 http 和 https 之间),那么 server.xml 中只需要有 2 个连接器。

  2. 如果您想在域名上有所不同,那么这将在 DNS 级别解决。

  3. 如果要在上下文名称(Web 应用程序名称)上有所不同,则应将 apache 放在前面(mod_proxy 或 mod_ajp),然后创建重写规则(mod_rewrite)。假设将/a/*/b/*全部重写为/c/*

  4. 如果您希望页面名称不同,则应使用 servlet 映射。

通过 mod_proxy 把 apache 放在 tomcat 前面很容易,网上有很多资源。非常糟糕的是复制应用程序(将所有内容加载两次)。

至于你的问题,我建议再次在 server.xml 中重复。

<Context docBase="myapp" path="/address1" reloadable="true" />
<Context docBase="myapp" path="/address2" reloadable="true" />

这是内存的杀手,也是会话机制、并发性等的杀手。

【讨论】:

  • 这并不能解决问题。您只需部署两个不同不同的 webapp。您必须使用 URL 重写。
  • 在 2 个地址的 1 个 Web 应用程序的解决方案在项目符号 1、2、3 中。这些建议都不意味着 2 个不同的 Web 应用程序。您的评论指的是哪个解决方案(段落)?
  • 基本身份验证是附加到 HTTP 请求的简单 HTTP 标头。它不应包含 uri(例如:“Authorization:Basic ZGV2OnNwaWwxMQ==”)。因此,如果两个站点的身份验证提供程序相同,则应该没有问题。否则,您始终可以在 Apache 上重写时附加标头。
【解决方案2】:

尝试使用 Tomcat 的 Rewrite Valve(文档here

{TOMCAT_HOME}/conf/server.xml

<Host name="localhost" ... >
    <Valve className="org.apache.catalina.valves.rewrite.RewriteValve" />
</Host>

{TOMCAT_HOME}/conf/Catalina/localhost/rewrite.config

RewriteCond %{REQUEST_URI} ^/XXX/.*$
RewriteRule ^/XXX/(.*)$ /YYY/$1 [L]

请注意 Tomcat 9 文档 (here) 中的此安全警告,

安全警告:由于 Java 的正则表达式匹配的方式,格式不正确的正则表达式模式容易受到“灾难性回溯”的影响,也称为“正则表达式拒绝服务”或 ReDoS。因此,对于 RewriteRule 模式应格外小心。一般来说,很难自动检测到这种易受攻击的正则表达式,因此一个好的防御方法是阅读一些关于灾难性回溯的主题。 OWASP ReDoS 指南是一个很好的参考。

【讨论】:

    【解决方案3】:

    尝试使用 crossContext 属性:

    <Context path="/YYY" docBase="XXX" crossContext="true"></Context>
    

    【讨论】:

    • 明确地说,它仅在您想使用 ServletContext#getContext() 访问它时启用返回其他上下文。但是,我不确定这如何适合问题中已发布的信息。
    • 是的,你是对的。前段时间我曾对此进行过调查,并记得我对此感到有些困惑。对于那个很抱歉。在发布建议之前应该多研究一下。
    猜你喜欢
    • 2015-05-18
    • 2012-06-26
    • 1970-01-01
    • 2013-09-18
    • 1970-01-01
    • 2011-01-02
    • 1970-01-01
    • 2017-01-30
    • 2011-02-01
    相关资源
    最近更新 更多