Spring 在Tomcat中在上下文之间转发请求
我希望能够使用Tuckey URLRewrite过滤器在Tomcat中进行跨上下文请求转发。例如,我希望能够使用SEO-/用户友好的URL(其中“组元素”不是已部署应用程序的名称)将传入请求路由到映射到应用程序“foo”的Java Spring控制器方法的URL,如。我正在使用Tomcat 7.0.27和URLRewite 3.2.0;我正在使用JavaSpring3.1Web应用程序 注释“to”过滤器参数元素的可选“context”属性:Spring 在Tomcat中在上下文之间转发请求,spring,tomcat,servlets,url-rewriting,tuckey-urlrewrite-filter,Spring,Tomcat,Servlets,Url Rewriting,Tuckey Urlrewrite Filter,我希望能够使用Tuckey URLRewrite过滤器在Tomcat中进行跨上下文请求转发。例如,我希望能够使用SEO-/用户友好的URL(其中“组元素”不是已部署应用程序的名称)将传入请求路由到映射到应用程序“foo”的Java Spring控制器方法的URL,如。我正在使用Tomcat 7.0.27和URLRewite 3.2.0;我正在使用JavaSpring3.1Web应用程序 注释“to”过滤器参数元素的可选“context”属性: If your application server
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"/>
如果您的应用程序服务器配置为允许“跨上下文”通信,则此属性可用于将请求转发(且仅转发、不重定向或其他“到”类型)到命名的servlet上下文。
例如,在Tomcat上,服务器配置中的应用程序上下文(server.xml或context.xml)需要crossContext=“true”选项。例如,前面提到的两个应用程序(“应用程序”和“论坛”)必须定义为:
考虑到这一点和其他因素,“上下文”属性似乎就是我要寻找的。但是,我无法正确启用跨上下文请求转发
以下是我在conf/server.xml中的“Context”条目应用程序“foo”:
<Context docBase="foo" path="/foo" reloadable="true" crossContext="true"/>
我的urlrewrite.xml文件和web.xml文件位于webapps/ROOT/web-INF/中。下面是它们的样子:
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>
<?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>
巴兹
/foo/app/group/300245/elements
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>
URL重写过滤器
org.tuckey.web.filters.urlrewrite.UrlRewriteFilter
对数电平
警告
URL重写过滤器
/*
上面在urlrewrite.xml中定义的规则是故意使用的基本规则和硬编码规则。在本例中,我只是想在开发“to”和“from”中的正则表达式之前,让规则的跨上下文方面发挥作用
当我使用该规则进行请求时,Tomcat返回一个404错误,表示“请求的资源(/baz)不可用。”我在“to”过滤器参数中尝试了一些变化,但没有任何效果。我还没有找到任何应该如何使用“上下文”的例子
关于如何让这种跨上下文请求过滤工作,有什么想法吗?有可能吗?我想我可以通过将foo.war重命名为ROOT.war或更改前面提到的根应用程序来实现我的目标,但我希望通过URLEWRITE来实现这一点,除非这样做不可行或表面上是个坏主意
如果显示更多我的配置将有所帮助,请让我知道。提前感谢您的任何意见
编辑:
感谢克里斯托弗·舒尔茨的帮助回答。在我的例子中,问题是由两件事引起的:1)webapps/ROOT/META-INF中没有context.xml文件,2)webapps/ROOT/WEB-INF/urlrewrite.xml中URL重写规则中的“to”元素出错
修复方法包括在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重写规则中“from”元素中隐含的上下文定义crossContext=“true”的上下文(这里是根)。无需在“to”URL重写规则中为应用程序显式定义上下文。换句话说,您不需要为该应用程序手动创建context.xml文件——因此继续上面的示例,您不需要手动定义context.xml文件并将其放入webapps/foo/META-INF/中
Schultz的回答反映了在官方Tomcat文档中定义上下文的建议:
问题的另一个原因是,我的第一篇文章中的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: 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>
<?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>
巴兹
/app/组/300245/元素
在我发表评论之后,请得出以下可能的结论:
我认为您将反向代理的概念与跨上下文混合在一起。跨上下文是在同一应用服务器内的两个web应用程序之间共享数据的方法。像“ApacheHTTP”这样的反向代理可以重写url以将其传递给它后面的某个服务器,从而有效地隐藏任何不需要的部分或执行负载平衡等其他操作
如果您的(真实的)webapp部署到/foo
,并且您希望动态地重写URL,如/group elements/baz
,以转发(而非重定向)到/foo/app/group/300245/elements
,则基础架构将是:客户端-->反向代理-->应用程序服务器,然后,您必须将重写过滤器部署到两个位置之一:/group elements
或/
上述配置似乎正在部署到ROOT(即/
),但随后将URL/baz
映射到/foo/app/group/300245/elements
。相反,您可能希望这样:
<rule>
<from>/group-elements/baz</from>
<to context="foo">/foo/app/group/300245/elements</to>
</rule>
/组元素/baz
/foo/app/group/300245/elements
看起来您试图点击http://example.com/baz
这是我本该工作的。最后一点神奇之处是让根
上下文跨上下文(请注意,您的webapp不需要跨上下文:只有urlrewrite一个需要跨上下文)。通过将crossContext=“true”
添加到webapps/ROOT/META-INF/context.xml,可以将ROOT
webapp更改为跨上下文
最后,您应该真正停止将
元素放在server.xml中:将它们留在那里基本上意味着您需要重新启动Tomcat以更改您的webapp部署