Spring的flashAttributes在反向代理后面不起作用


问题内容

尝试使RedirectAttributes的flashAttributes工作时遇到问题。我已经在Tomcat 7.0上建立了一个使用Spring
MVC构建的网站,并使用Apache mod_proxy和ajp建立了反向代理。

这是我用于测试目的的控制器的摘录:

@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的响应:
Flash消息:Flash消息
Session消息:会话消息

apache mod_proxy后面
Flash消息:
会话消息:会话消息

通过代理访问网站时为什么没有Flash消息?

我签出了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。


问题答案:

更改反向代理中的上下文路径通常是解决问题的方法。假设这是问题,您有两个选择。

  1. 通过将MyApp.war重命名为ROOT.war(如果将MyApp目录重命名为ROOT,则将其命名为ROOT),将您的应用程序部署为Tomcat上的ROOT应用程序。

  2. 启动一个合适的工具来查看HTTP标头和内容(Wireshark,FireBug,ieHttpHeaders等-选择一个适用于您和您的环境的标头),并找到所有需要更改且未更改路径的位置。使用mod_headers和mod_substitute(或等效项)在反向代理中进行必要的更改。

就我个人而言,我总是选择1,因为它更容易,更快捷,更容易且更不容易出错。当我坚持要不得不在反向代理中更改上下文路径时,我花了很多天来帮助客户调试问题。

为什么会这样?

当反向代理中的上下文路径更改时,可能需要在许多地方更改该路径:

  1. 从用户代理收到的请求URL
  2. 后端服务器返回的重定向位置
  3. 网页链接的URL
  4. 应用程序(或应用程序正在使用的库)设置的自定义HTTP响应标头
  5. Cookie路径

ProxyPass处理1

ProxyPassReverse处理位置,内容位置和URI标头(2)

ProxyPassReverseCookiePath处理5

mod_proxy无法处理情况4或情况5,因为这很难解决。您最终必须根据情况编写一些非常仔细的正则表达式才能获得所需的结果。

我怀疑flashAttributes使用的是包含路径的自定义HTTP标头,这就是为什么它们不起作用的原因。该会话将正常运行,因为该会话通常由会话cookie管理,并且您已配置ProxyPassReverseCookiePath。