spring - 在 Tomcat 中的上下文之间转发请求

标签 spring tomcat servlets url-rewriting tuckey-urlrewrite-filter

我希望能够使用 Tuckey URLRewrite 过滤器在 Tomcat 中进行跨上下文请求转发。例如,我希望能够使用 SEO/用户友好的 URL 来路由传入请求,例如 http://example.com/group-elements/300245/some-descriptive-text ,其中“group-elements”不是已部署应用程序的名称,映射到应用程序“foo”的 Java Spring Controller 方法的 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 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 中的“上下文”入口应用程序“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。

修复涉及将适当的 context.xml 文件放入 webapps/ROOT/META-INF。供遇到此问题的任何其他人引用,该文件最终看起来像这样:

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 的回答反射(reflect)了在官方 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>

最佳答案

如果您的(真实的)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>

看起来你试图打http://example.com/baz我本来希望能工作的。最后一点魔法是制作 ROOT context 跨上下文(请注意,您的 webapp 不需要跨上下文:只有 urlrewrite 需要)。您可以更改 ROOT webapp 将由 addint 跨上下文 crossContext="true"webapps/ROOT/META-INF/context.xml .

最后,你真的应该停止输入 <Context> server.xml 中的元素:将它们留在那里基本上意味着您需要重新启动 Tomcat 以更改您的 webapp 部署。

关于spring - 在 Tomcat 中的上下文之间转发请求,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11001623/

相关文章:

java - Hibernate和Spring数据jpa同时使用?

java - Spring mvc 调度程序问题

java - Eclipse 中的 Servlet - 放置静态内容的位置

java - 如何将 context.xml 文件添加到嵌入式 tomcat 服务器

java - SecureRandom 数字中的算法

java - 无法配置 JAAS 身份验证

java - Aspectj(使用 spring)- 在没有传播方法的情况下仅在抛出方法上记录一次异常抛出

java - 是否存在 Eclipse 部署程序集日志?

java - 获取 native 层版本时出错 : java. lang.UnsatisfiedLinkError : no sapjco3 in java. library.path

eclipse - 为什么 Eclipse 在仅保存单个 JavaScript、HTML 和 CSS 文件方面如此缓慢?