Spring flash 属性在反向代理后面不起作用

标签 spring tomcat spring-mvc redirect proxy

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

我面临的问题在this question中也有描述。 ,但那里提供的答案根本不适用于我的情况(我使用的是 Tomcat 的单个实例)。

这是我用于测试目的的 Controller 的片段:

@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 的响应:
闪信:一条闪信
session 消息: session 消息

apache mod_proxy 背后:
Flash message:
Session message: session 消息

为什么通过代理访问网站时没有闪现信息?

我检查了 RedirectAttributesModelMap.java 的代码和 ModelMap.java但是那里没有足够的信息(显然逻辑是在别处实现的)。

注意:我总是可以回退到 session 属性来实现我的目标,但对于那些在反向代理后面使用 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. 将您的应用程序部署为 Tomcat 上的 ROOT 应用程序,方法是将 MyApp.war 重命名为 ROOT.war(如果是目录,则将 MyApp 目录重命名为 ROOT)。

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

就个人而言,我总是选择 1,因为它更简单、更快捷、更容易,而且更不容易出错。当客户坚持必须更改反向代理中的上下文路径时,我花了几天时间帮助他们调试问题。

为什么会这样?

当反向代理中的上下文路径发生变化时,有很多地方可能需要更改该路径:

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

ProxyPass 处理 1

ProxyPassReverse 处理 Location、Content-Location 和 URI header (2)

ProxyPassReverseCookiePath 句柄 5

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

我怀疑 flashAttributes 使用的是包含路径的自定义 HTTP header ,这就是它们不起作用的原因。 session 将按照通常由 session cookie 管理的方式工作,并且您已配置 ProxyPassReverseCookiePath。

关于Spring flash 属性在反向代理后面不起作用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19367531/

相关文章:

java - 如何动态地将外部定义的bean定义添加到Spring上下文中?

java.io.FileNotFoundException :/target/test. 日志

java - 停止运行带有 while (true) 循环的 web 应用程序的 tomcat 服务器时遇到问题

java - Spring @PathVariable 不起作用

java - GWT java.lang.NoClassDefFoundError : com/google/gwt/util/tools/Utility

Tomcat KeyStore 环境路径

javascript - D3无法设置附加对象的样式

java - 使用@PropertySource(SpringBoot)使用通配符读取多个属性文件

java - 如何在 Spring 应用程序中处理生产数据库的架构升级

java - 使用 Jackson 将 Java 对象序列化为 JSON 时抑制包装器对象