我希望能够使用Tuckey URLRewrite过滤器在Tomcat中进行跨上下文请求转发。例如,我希望能够将传入的请求与一个SEO- /用户友好的URL(如http://example.com/group-elements/300245/some-descriptive-text)路由到URL,其中“group-elements”不是已部署应用程序的名称映射到应用程序'foo'的Java Spring控制器方法,如http://example.com/foo/app/group/300245/elements。我正在使用Tomcat 7.0.27和URLRewrite 3.2.0;我正在使用Java Spring 3.1 Web应用程序。
URLRewrite 3.20 documentation注意到'to'过滤器参数元素的可选'context'属性:
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"/>
鉴于这一点和original discussion about the feature,'context'属性似乎正是我正在寻找的。但是,我无法正确启用跨上下文请求转发。
这是conf / server.xml中的'Context'条目应用程序'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或更改提交的根应用程序here来实现我想要做的事情,但我想通过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”的上下文。没有必要在'to'URL重写规则中明确定义应用程序的上下文。换句话说,您不需要为该应用程序手动创建context.xml文件 - 所以继续上面的示例,您不需要手动定义并将context.xml文件放入webapps / foo / META-INF /.
Schultz的回答反映了在官方Tomcat文档中定义上下文的建议:http://tomcat.apache.org/tomcat-7.0-doc/config/context.html#Defining_a_context。
问题也是由于我的初始帖子中的URL重写规则出错了。正确的版本应该是:
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: the use of '/app' instead of '/foo/app/' below -->
<to context="foo">/app/group/300245/elements</to>
</rule>
</urlrewrite>
答案 0 :(得分:3)
如果您的(真实)网络应用已部署到/foo
,并且您希望即时重写网址,例如/group-elements/baz
转发( 不 重定向到/foo/app/group/300245/elements
,然后您必须将重写过滤器部署到以下两个位置之一:/group-elements
或/
。
上述配置似乎正在部署到ROOT( /
),但随后将网址/baz
映射到/foo/app/group/300245/elements
。相反,你可能想要这个:
<rule>
<from>/group-elements/baz</from>
<to context="foo">/foo/app/group/300245/elements</to>
</rule>
看起来你 试图点击http://example.com/baz
,我原本希望这样做。最后一点魔法将是ROOT
上下文交叉上下文(请注意,您的webapp不需要是跨上下文的:只有urlrewrite才能实现)。您可以将ROOT
webapp更改为addint crossContext="true"
到webapps/ROOT/META-INF/context.xml
的跨上下文。
最后,您应该停止在server.xml中放置<Context>
元素:将它们留在那里基本上意味着您需要重新启动Tomcat才能更改您的Web应用程序部署。
答案 1 :(得分:1)
在评论之后我来做这个可能的结论:
我认为您正在将反向代理的概念与跨上下文混合在一起。跨上下文是在同一应用程序服务器中的两个Web应用程序之间共享数据的方法。像'Apache http'这样的反向代理可以重写一个url,将其传递给它后面的某个服务器,有效地隐藏任何不需要的部分或执行其他操作,如负载平衡。
基础设施将是:客户端 - &gt;反向代理 - &gt;应用服务器