【问题标题】:Non-static webapp alias非静态 webapp 别名
【发布时间】:2015-06-06 17:04:48
【问题描述】:

我想知道,是否有一种干净的方法可以让名称未出现在请求 url 中的 webapp 响应请求。在某种程度上,url 应该是 webapp 的别名。此外,别名不应该是静态的或使用这个单一的 web 应用程序固定,而是我需要能够轻松更改别名后面的 web 应用程序以进行版本增量。 我想到的事情是

  • 构建一个“外观”webapp 来重定向请求
  • 重命名整个 webapp

这两种想法都不会带来预期的结果。我想要一个更轻量级的解决方案。

这可能吗?

【问题讨论】:

  • 通常这是通过前端网络系统实现的,可以是负载平衡设备,也可以是进行重写的 apache/nginx 安装。
  • @Affe 好的,但这听起来有点开销?我不希望我的整个流量被重定向,只是请求容器内的单个 webapp。您能否详细说明一个简单的用例场景?
  • 你目前用什么做前端?您是否将tomcat直接暴露在互联网上? nginx.org/en/docs/http/ngx_http_rewrite_module.html
  • 嗯,tomcat webapps(webservices)主要由java或php应用程序内部引用。此外,一些 web 应用程序旨在用于可从外部访问的 API,这就是需要别名的原因。

标签: java web-services tomcat web-applications


【解决方案1】:

如果您只想使用 tomcat 方法,您可以在 tomcat context.xml 中静态映射 webapp 的路径,定义上下文并将request path(“路径”)映射到webapp dir(“docBase”) .

只需将此添加到您的<tomcatDir>/conf/context.xml

<Context 
  path="" 
  docBase="/<pathToYourWebapp>/<yourApp>" 
/>

这有一个副作用,当然,您只能拥有一个 webapp,因为每个请求和 / 都映射到您的 webapp。

更多信息请参见http://tomcat.apache.org/tomcat-8.0-doc/config/context.html#Common_Attributes

【讨论】:

  • 这会有一个缺点,如果上下文文件后面的 webapp 发生变化,我必须为每个公开的 webapp 维护一个 context.xml 文件并修改它们。我对吗?另外我认为,在进行这些修改后,我需要重新启动 tomcat。
  • 如果您将此 &lt;Context/&gt; 节点添加到 context.xml (conf/context.xml),它将是 一个节点 每个 webapp 在唯一的 context.xml。我认为您还可以在conf/Catalina/localhost/&lt;webappName&gt; 中为每个 web 应用添加一个 context.xml,但这是另一回事。 @Affe 提出了另一种方法(“...负载平衡设备或 apache/nginx”)-无需配置 tomcat,而是在之前配置一些东西
【解决方案2】:

感谢 Alexander 的帖子,我找到了正确的轨道,但我使用了一些额外的工作,这或多或少是我最初的问题中第 1 点中提到的外观 webapp。我将向任何感兴趣的人展示我的整个方法:

首先,我将所有标准 web 应用程序部署在 /tomcat/webapps 中,并启用了一个标准 context.xmlautoDeploy 模式。为了捕获与已部署上下文之一不匹配的所有其他请求,我设置了一个新的 webapp,它充当不匹配请求的默认 webapp。我们就叫它dispatcher-app吧。

为了使这一项工作,我必须将其设置为ROOT。为了以原始名称部署它,我将它定位在 /tomcat/webapps2 下,并在 /tomcat/conf/Catalina/localhost/ROOT.xml 中将其关联到 context.xml。有必要将其放在/webapps 之外,以防止在 tomcat 中使用用于其他 webapps 的 autoDeploy 模式进行双重部署。更多信息可以在这里找到:http://tomcat.apache.org/tomcat-7.0-doc/config/context#Naming

ROOT.xml 看起来像这样:

<Context
    path=""
    docBase="/path/to/tomcat-base/webapps2/dispatcher-app"
    crossContext="true"
/>

dispatcher-app的web.xml中确定,它使用了

<servlet-mapping>
    <url-pattern>/</url-pattern>
 </servlet-mapping>

内部的dispatcher-app 查找用户使用uriInfo.getAbsolutePath() 请求的原始路径。然后,它将来自 url 的应用程序与在 tomcat 中运行的应用程序进行匹配,这些应用程序从自定义配置文件中得知。如果匹配,配置文件就知道应该转发到哪个应用程序。例如,用户请求myserver/webapp-1/test?param=value,并转发到myserver/webapp-1.1.2/test?param=value。如果应用程序版本发生变化,可以在配置文件中手动更新要转发到的 webapp。

实际转发应该使用

RequestDispatcher dispatcher=servletContext.getRequestDispatcher(redirectTo);
dispatcher.forward(request, response);

因为转发对用户是不可见的。

由于无法运行(请参阅Cross-context request forwarding in tomcat results in java.lang.ClassCastException: org.glassfish.jersey.message.internal.TracingLogger),我现在只使用了 307 重定向。

return Response.status(307).location(new URI(redirectTo)).build();

这个的缺点是,浏览器会在地址栏中显示重定向 URL。

更新: RequestDispatcher 现在可以工作了,只是不适用于上面提到的这种特殊情况/webapp。所以我更喜欢重定向方法。

需要注意的一点是,第二个 webapp 上基于容器的身份验证(例如 realm)将无效(就像我们执行前向“后”tomcat 外观一样),因此dispatcher-app 本身需要一个身份验证方法或者需要使用其他机制进行身份验证,例如RequestFilter

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2013-07-05
    • 2016-08-29
    • 1970-01-01
    • 1970-01-01
    • 2020-12-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多