4

我希望能夠使用Tuckey URLRewrite過濾器在Tomcat中進行跨上下文請求轉發。例如,我希望能夠將帶有SEO /用戶友好URL(如http://example.com/group-elements/300245/some-descriptive-text,其中「group-elements」不是部署的應用程序的名稱)的傳入請求路由到映射到Java的URL Spring應用程序'foo'的控制器方法,如http://example.com/foo/app/group/300245/elements。我正在使用Tomcat 7.0.27和URLRewrite 3.2.0;我正在使用Java Spring 3.1 Web應用程序。在Tomcat上下文之間轉發請求

URLRewrite 3.20 documentation注意到一個可選的「語境」的屬性爲「到」過濾器參數元素:

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的「語境」屬性似乎正是我要找的。但是,我無法正確啓用跨上下文請求轉發。

下面是的conf/server.xml中我的 '語境' 入境申請 '富':

<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嘗試執行此操作,除非這樣做不可行或者它的臉上一個壞主意。

如果顯示更多我的配置會有所幫助,請告訴我。預先感謝您的任何意見。

編輯

感謝克里斯託弗·舒爾茨爲有用的答案。在我的情況下,問題是由兩件事引起的:1)webapps/ROOT/META-INF中沒有context.xml文件,2)webapps/URL中的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" /> 

正如舒爾茨提到,它僅適用於具有crossContext =「真」在一個給定的URL重寫規則在「從」元素所隱含的角度來定義(在這裏,這是ROOT)上下文必要的。沒有必要在'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

也許一個愚蠢的問題,但你的網址沒有任何關於應用程序中的跨環境的工作嗎? – tom

+0

如果我正確理解你的問題,不需要。 SEO- /用戶友好的URL目前沒有映射到任何東西,併產生一個404。 – jqp

+0

爲什麼你期望除了具有交叉上下文的404以外的其他東西,如果你已經有404沒有交叉上下文? – tom

回答

3

如果你的(真正的)Web應用部署到/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上下文交叉上下文(請注意,您的web應用程序不需要跨越上下文:只有urlrewrite一個)。您可以將ROOT webapp更改爲交叉上下文addint crossContext="true"webapps/ROOT/META-INF/context.xml

最後,您應該停止在server.xml中放入<Context>元素:將它們留在那裏基本上意味着您需要重新啓動Tomcat以更改您的webapp部署。

+0

謝謝,上述答案中的方法運作良好。就我而言,這裏的關鍵是在webapps/ROOT/META-INF/context.xml中定義元素。 – jqp

+0

呵呵,上面的代碼示例中對'規則'語法的更正:'to'元素值中的「/ foo/app」段不正確;它應該只是「/ app」,即/app/group/300245/elements。 – jqp

1

我來做到這一點可能的結論意見後:

我認爲你是混合反向代理的概念有交叉上下文。跨上下文是在同一應用程序服務器中的兩個Web應用程序之間共享數據的方法。像'Apache http'這樣的反向代理可以重寫一個url,將它傳遞給它後面的某個服務器,從而有效地隱藏任何不需要的部分或執行其他操作,如負載平衡。

的基礎設施將是:客戶端 - >反向代理 - >應用程序服務器

+0

儘管Tomcat沒有部署傳統的應用程序,但它仍然不是'Tomcat'中的上下文嗎?我描述的用例與功能的初始修補程序[此處](http://code.google.com/p/urlrewritefilter/issues/detail?id=17)中描述的有何不同?我可能在閱讀時錯過了一些東西,但補丁的初始使用看起來好像不是從一個部署的Web應用程序轉發到另一個部署的Web應用程序 - 或者它是? – jqp

+0

我認爲如果你想使用這個過濾器,你需要在ROOT中部署一個帶有這個過濾器的應用程序。如果你不這樣做,那麼沒有人會在那個URL上聽,所以除了404之外什麼都不會發生。雄貓不是魔術。它只做你告訴它做的事情。 – tom

+0

我認爲值得在這裏提及,'客戶端 - >反向代理 - >應用程序'基礎設施似乎是一個可能的選項,以啓用我想要做的事情,但不是必需的。使用Schultz的答案中提到的方法,可以僅在Tomcat中進行跨上下文轉發。術語混淆(至少在我的結尾)可能會造成一些混淆。 – jqp