我希望能够使用Tuckey URLRewrite过滤器在Tomcat中进行跨上下文请求转发。例如,我希望能够使用SEO //用户友好的URL(例如http://example.com/group-elements/300245/some-descriptive- text)路由传入请求,其中“ group-elements “不是已部署的应用程序的名称,而是映射到应用程序’foo’的Java Spring控制器方法的URL,例如http://example.com/foo/app/group/300245/elements。我正在使用Tomcat 7.0.27和URLRewrite 3.2.0;我正在使用Java Spring 3.1 Web应用程序。
所述URLRewrite 3.20文档注意到一个可选的“上下文”用于“到”滤波器参数元素属性:
If your application server is configured to allow "cross context" communication then this attribute can be used to forward (and only forward, not redirect or other "to" types) requests to a named servlet context. On Tomcat, for instance, the application contexts in the server configuration (server.xml or context.xml) need the option crossContext="true". For instance, the two applications mentioned before ("app" and "forum") have to be defined as: <Context docBase="app" path="/app" reloadable="true" crossContext="true"/> <Context docBase="forum" path="/forum" reloadable="true" crossContext="true"/>
鉴于此以及对该功能的原始讨论,“ context”属性似乎是我想要的。但是,我无法正确启用跨上下文请求转发。
这是conf / server.xml中我的“上下文”条目应用程序“ foo”:
<Context docBase="foo" path="/foo" reloadable="true" crossContext="true"/>
我在webapps / ROOT / WEB-INF /中有urlrewrite.xml文件和web.xml文件。它们是这样的:
urlrewrite.xml:
<?xml version="1.0" encoding="utf-8"?> <!DOCTYPE urlrewrite PUBLIC "-//tuckey.org//DTD UrlRewrite 3.2//EN" "http://tuckey.org/res/dtds/urlrewrite3.2.dtd"> <urlrewrite> <rule> <from>baz</from> <!-- Note: this 'to' element's value has an error. See the edit at bottom of this post for corrected version. --> <to context="foo">/foo/app/group/300245/elements</to> </rule> </urlrewrite>
web.xml:
<?xml version="1.0" encoding="ISO-8859-1"?> <web-app xmlns="http://java.sun.com/xml/ns/j2ee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-app_2_5.xsd" version="2.5"> <filter> <filter-name>UrlRewriteFilter</filter-name> <filter-class>org.tuckey.web.filters.urlrewrite.UrlRewriteFilter</filter-class> <init-param> <param-name>logLevel</param-name> <param-value>WARN</param-value> </init-param> </filter> <filter-mapping> <filter-name>UrlRewriteFilter</filter-name> <url-pattern>/*</url-pattern> </filter-mapping> </web-app>
上面在urlrewrite.xml中定义的规则是故意的并且是硬编码的。在这种情况下,我只是试图在开发“ to”和“from”的正则表达式之前使规则的跨上下文方面起作用。
当我请求使用该规则的http://example.com/baz时,Tomcat返回404错误,提示“请求的资源(/ baz)不可用”。我尝试了“ to”过滤器参数的一些变体,但是什么都没起作用。而且我还找不到任何有关如何使用“上下文”的示例。
关于如何使这种跨上下文请求过滤起作用的任何想法?可能吗 我想我可以通过将foo.war重命名为ROOT.war或按此处所述更改根应用程序来实现我要执行的操作,但是我想通过URLRewrite尝试执行此操作,除非这样做不可行或不好的主意。
如果显示更多我的配置有帮助,请告诉我。预先感谢您的任何投入。
编辑 :
感谢Christopher Schultz的有用答案。就我而言,问题是由两件事引起的:1)webapps / ROOT / META- INF中没有context.xml文件,以及2)webapps /中URL重写规则中的“ to”元素中有错误ROOT / WEB-INF / urlrewrite.xml。
该修复程序涉及在webapps / ROOT / META-INF中放入适当的context.xml文件。为了给遇到此问题的其他人提供参考,该文件的最终外观如下:
webapps / ROOT / META-INF / context.xml
<?xml version='1.0' encoding='utf-8'?> <Context docBase="ROOT" path="/" reloadable="true" crossContext="true" />
正如Schultz所提到的,仅需为给定URL重写规则(此处为ROOT)中“ from”元素中隐含的上下文定义一个带有crossContext =“ true”的上下文。不必在“收件人” URL重写规则中为应用程序明确定义上下文。换句话说,您不需要为该应用程序手动创建一个context.xml文件- 因此,继续上面的示例,您将不需要手动定义一个context.xml文件并将其放入webapps / foo / META-INF /。
舒尔茨的答案反映了官方Tomcat文档中定义上下文的建议:http : //tomcat.apache.org/tomcat-7.0-doc/config/context.html#Defining_a_context。
该问题还由以下事实引起:我的初始帖子中的URL重写规则有错误。正确的版本应该是:
<?xml version="1.0" encoding="utf-8"?> <!DOCTYPE urlrewrite PUBLIC "-//tuckey.org//DTD UrlRewrite 3.2//EN" "http://tuckey.org/res/dtds/urlrewrite3.2.dtd"> <urlrewrite> <rule> <from>baz</from> <!-- Note: the use of '/app' instead of '/foo/app/' below --> <to context="foo">/app/group/300245/elements</to> </rule> </urlrewrite>
如果您的(实际)Web应用程序已部署到/foo并且您想要即时重写URL /group-elements/baz以便转发( 而不是 重定向到)/foo/app/group/300245/elements,那么您将不得不将重写过滤器部署到以下两个位置之一:/group- elements或/。
/foo
/group-elements/baz
/foo/app/group/300245/elements
/group- elements
/
上面的配置似乎正在部署到ROOT( 是 /),然后将URL映射/baz到/foo/app/group/300245/elements。相反,您可能想要这样:
/baz
<rule> <from>/group-elements/baz</from> <to context="foo">/foo/app/group/300245/elements</to> </rule>
看来您 正在 尝试达到http://example.com/baz预期的效果。魔术的最后一点是使ROOT上下文成为跨上下文(请注意,您的Web应用程序不必是跨上下文的:只需使用urlrewrite即可)。您可以更改ROOTWeb应用程序是由addint跨情境crossContext="true"来webapps/ROOT/META-INF/context.xml。
http://example.com/baz
ROOT
crossContext="true"
webapps/ROOT/META-INF/context.xml
最后,您应该真正停止<Context>在server.xml中放置元素:将它们保留在其中基本上意味着您需要重新启动Tomcat才能更改Webapp部署。
<Context>