非静态 webapp 别名
Non-static webapp alias
我想知道,是否有一种干净的方法可以让名称未出现在请求中的网络应用程序回答请求 url。在某种程度上,url 应该是 webapp 的别名。此外,别名不应该是静态的或固定在这个单一的 webapp 上,而是我需要能够轻松地更改别名后面的 webapp 以实现版本增量。
我想到的是
- 构建一个 "facade" webapp 来重定向请求
- 重命名完整的网络应用程序
这两种想法都没有达到预期的结果。我想要一个更轻量级的解决方案。
这可能吗?
如果你只想用 tomcat 来做,你可以在 tomcat context.xml
中静态映射你的 webapp 路径定义一个上下文并映射 request path
( "path") 到 webapp dir
("docBase").
只需将此添加到您的 <tomcatDir>/conf/context.xml
:
<Context
path=""
docBase="/<pathToYourWebapp>/<yourApp>"
/>
这有一个副作用,你只能有一个网络应用程序,当然,因为每个请求和 /
都映射到你的网络应用程序。
有关详细信息,请参阅 http://tomcat.apache.org/tomcat-8.0-doc/config/context.html#Common_Attributes。
感谢 Alexander 的 post,我找到了正确的轨道,但我使用了一些额外的工作,这或多或少是我最初问题中第 1) 点中提到的 facade webapp。我将向任何感兴趣的人展示我的整个方法:
首先,我在 /tomcat/webapps
中部署了所有标准 Web 应用程序,并启用了一个标准 context.xml
和 autoDeploy
模式。为了捕获与部署的上下文之一不匹配的所有其他请求,我设置了一个新的 webapp,它充当不匹配请求的默认 webapp。我们称它为 dispatcher-app
.
要使这一项有效,我必须将其设置为 ROOT
。为了以其原始名称部署它,我将其定位在 /tomcat/webapps2
下,并将其关联的 context.xml
定位在 /tomcat/conf/Catalina/localhost/ROOT.xml
中。有必要将它放在 /webapps
之外,以防止在 tomcat 中使用其他 Web 应用程序使用的自动部署模式进行双重部署。可以在此处找到更多信息: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);
因为转发对用户不可见。
因为我做不到 运行(参见 ),我现在只是使用了 307 重定向。
return Response.status(307).location(new URI(redirectTo)).build();
这个的缺点是,浏览器会在地址栏中显示重定向URL。
更新:
RequestDispatcher
现在可以工作了,只是不适用于上面提到的这个特殊的 case/webapp。所以我更喜欢重定向方法。
需要注意的一件事是,第二个 webapp 上的基于容器的身份验证(例如 realm
)将无效(正如我们在前向 'behind' tomcat 门面所做的那样)因此 dispatcher-app
本身需要一种身份验证方法,或者需要使用另一种机制进行身份验证,例如 RequestFilter
.
我想知道,是否有一种干净的方法可以让名称未出现在请求中的网络应用程序回答请求 url。在某种程度上,url 应该是 webapp 的别名。此外,别名不应该是静态的或固定在这个单一的 webapp 上,而是我需要能够轻松地更改别名后面的 webapp 以实现版本增量。 我想到的是
- 构建一个 "facade" webapp 来重定向请求
- 重命名完整的网络应用程序
这两种想法都没有达到预期的结果。我想要一个更轻量级的解决方案。
这可能吗?
如果你只想用 tomcat 来做,你可以在 tomcat context.xml
中静态映射你的 webapp 路径定义一个上下文并映射 request path
( "path") 到 webapp dir
("docBase").
只需将此添加到您的 <tomcatDir>/conf/context.xml
:
<Context
path=""
docBase="/<pathToYourWebapp>/<yourApp>"
/>
这有一个副作用,你只能有一个网络应用程序,当然,因为每个请求和 /
都映射到你的网络应用程序。
有关详细信息,请参阅 http://tomcat.apache.org/tomcat-8.0-doc/config/context.html#Common_Attributes。
感谢 Alexander 的 post,我找到了正确的轨道,但我使用了一些额外的工作,这或多或少是我最初问题中第 1) 点中提到的 facade webapp。我将向任何感兴趣的人展示我的整个方法:
首先,我在 /tomcat/webapps
中部署了所有标准 Web 应用程序,并启用了一个标准 context.xml
和 autoDeploy
模式。为了捕获与部署的上下文之一不匹配的所有其他请求,我设置了一个新的 webapp,它充当不匹配请求的默认 webapp。我们称它为 dispatcher-app
.
要使这一项有效,我必须将其设置为 ROOT
。为了以其原始名称部署它,我将其定位在 /tomcat/webapps2
下,并将其关联的 context.xml
定位在 /tomcat/conf/Catalina/localhost/ROOT.xml
中。有必要将它放在 /webapps
之外,以防止在 tomcat 中使用其他 Web 应用程序使用的自动部署模式进行双重部署。可以在此处找到更多信息: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);
因为转发对用户不可见。
因为我做不到 运行(参见
return Response.status(307).location(new URI(redirectTo)).build();
这个的缺点是,浏览器会在地址栏中显示重定向URL。
更新:
RequestDispatcher
现在可以工作了,只是不适用于上面提到的这个特殊的 case/webapp。所以我更喜欢重定向方法。
需要注意的一件事是,第二个 webapp 上的基于容器的身份验证(例如 realm
)将无效(正如我们在前向 'behind' tomcat 门面所做的那样)因此 dispatcher-app
本身需要一种身份验证方法,或者需要使用另一种机制进行身份验证,例如 RequestFilter
.