2013-10-14 106 views
0

我在嘗試使RedirectAttributes的flashAttributes正常工作時遇到問題。 我已經使用Apache mod_proxy和ajp設置了一個使用Tomcat 7.0上的Spring MVC和反向代理構建的網站。Spring的flashAttributes不支持反向代理

我面臨的問題也在this question中描述,但在那裏提供的答案根本不適用於我的情況(我正在使用一個單一的Tomcat實例)。

這是從控制器片段我使用的用於測試目的:

@RequestMapping(value = "/land", method = RequestMethod.GET) 
    public String land(RedirectAttributes redirectAttrs, Model model) { 
    return "redirect_landing"; 
} 

@RequestMapping(value = "/redirect", method = RequestMethod.GET) 
public String redirect(RedirectAttributes redirectAttrs, HttpSession session) { 

    // add a session message 
    session.setAttribute("sessionMessage", "a session message"); 

    // add a flash message 
    redirectAttrs.addFlashAttribute("flashMessage", "a flash message"); 

    // define the base url 
    String baseUrl = "http://localhost:8080/MyApp/"; 
    // String baseUrl = "http://dev.myapp.lan/"; 

    return "redirect:" + baseUrl + "land"; 
} 

而且模板是如此簡單:

Flash message: ${flashMessage} 
Session message: ${sessionMessage} 

相同的代碼給出了不同的結果,這取決於無論我是直接通過Tomcat還是通過Apache反向代理訪問網站:

Tomcat的回覆:
閃光消息:閃光消息
會話消息:會話消息

的Apache的mod_proxy背後:
閃光燈消息:
會話消息:會話消息

訪問的時候爲什麼沒有提示信息通過代理網站?

我檢出了RedirectAttributesModelMap.javaModelMap.java的代碼,但是那裏沒有足夠的信息(顯然邏輯是在別處實現的)。

注:我隨時可以回落到會話屬性來實現我的目標,但這個問題對於那些誰使用Tomcat後面反向代理


代理服務器配置(片段)感覺足夠有趣:

<VirtualHost *:80> 
    ServerName dev.myapp.lan  

    ProxyPass/ajp://localhost:8009/MyApp/ 

    ProxyPassReverseCookiePath /MyApp/
    ProxyPassReverseCookieDomain localhost MyApp 

    ErrorLog /var/log/apache2/phonebook-error.log 
    LogLevel warn 

    CustomLog /var/log/apache2/phonebook-access.log combined 
</VirtualHost> 

TIA。

+0

您是如何設定的反向代理。至少我們需要查看ProxyPass指令以及理想的所有代理配置。 –

+0

@MarkThomas我使用我正在使用的apache配置中的一段代碼更新了我的問題。請讓我知道這是否足夠。非常感謝。 – dimi

回答

2

更改逆向代理中的上下文路徑通常是爲了解決問題。假設這是問題,你有兩個選擇。

  1. 部署應用程序作爲在Tomcat的ROOT應用程序通過重命名MyApp.war到ROOT.war(或MyApp的目錄ROOT,如果它是一個目錄)。

  2. 啓動一個合適的工具來查看HTTP標頭和內容(Wireshark,FireBug,ieHttpHeaders等 - 選擇適合您和您的環境的工具),並找到需要更改路徑的所有位置並沒有。使用mod_headers和mod_substitute(或等價物)在反向代理中進行必要的更改。

就我個人而言,我總是選擇1,因爲它更簡單,更快,更容易,更不容易出錯。我已經花了數天的時間幫助客戶調試問題,因爲他們堅持認爲他們必須更改逆向代理中的上下文路徑。

爲什麼會發生這種情況?

當上下文路徑反向代理的變化有許多地方這條道路可能需要改變:

  1. 是從用戶代理
  2. 一個重定向的位置,是接收到的請求的URL通過後端服務器返回
  3. 網址,網頁中的鏈接由應用程序(或應用程序正在使用庫)
  4. 餅乾PA設置
  5. 自定義HTTP響應頭部份

的ProxyPass處理1個

ProxyPassReverse處理地點,內容位置和URI報頭(2)

ProxyPassReverseCookiePath處理,因爲這是5

mod_proxy的不處理殼體4或殼體5很難得到正確的。您最終不得不根據具體情況編寫一些非常謹慎的正則表達式以獲得理想的結果。

我懷疑flashAttributes正在使用包含路徑的自定義HTTP標頭,這就是爲什麼它們不起作用。會話將按照通常由會話cookie管理的方式工作,並且您已配置ProxyPassReverseCookiePath。

+0

事實上,更改Tomcat的server.xml配置文件上的上下文路徑完成了這項工作。作爲一名Tomcat專家,你能解釋一下爲什麼會發生這種情況?代理不應該隱藏上下文路徑和請求URL路徑之間的差異嗎?爲什麼flashAttributes受到影響,而會話屬性正常工作?謝謝。 – dimi

+0

感謝您的精心解答,它非常有幫助。在管理(存儲和檢索)flashAttributes時,似乎要考慮請求路徑。對於任何感興趣的人,我在[AbstractFlashMapManager]的源代碼中找到了更多細節(https://github.com/spring-projects/spring-framework/blob/1204d2aef4afdefb4ba73c86565aab3f5b2a6931/spring-webmvc/src/main/java/org /springframework/web/servlet/support/AbstractFlashMapManager.java)(請參閱getMatchingFlashMap方法)。 – dimi