感谢 Alexander 的帖子,我找到了正确的轨道,但我使用了一些额外的工作,这或多或少是我最初的问题中第 1 点中提到的外观 webapp。我将向任何感兴趣的人展示我的整个方法:
首先,我将所有标准 web 应用程序部署在 /tomcat/webapps 中,并启用了一个标准 context.xml 和 autoDeploy 模式。为了捕获与已部署上下文之一不匹配的所有其他请求,我设置了一个新的 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。