我在尝试使RedirectAttributes的flashAttributes工作时遇到问题。 我在Tomcat 7.0上设置了一个使用Spring MVC构建的网站,并使用Apache mod_proxy和ajp设置了一个反向代理。
我面临的问题也在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的回复:
Flash消息:flash消息
会话消息:会话消息
在apache mod_proxy后面:
Flash消息:
会话消息:会话消息
为什么通过代理访问网站时没有flash消息?
我查看了RedirectAttributesModelMap.java和ModelMap.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 :(得分:2)
更改反向代理中的上下文路径通常是解决问题的方法。假设这是问题,你有两个选择。
将您的应用程序部署为Tomcat上的ROOT应用程序,方法是将MyApp.war重命名为ROOT.war(如果是目录,则将MyApp目录重命名为ROOT)。
启动一个合适的工具来查看HTTP标头和内容(Wireshark,FireBug,ieHttpHeaders等 - 选择适合您和您的环境的工具)并查找路径需要的所有位置改变了,但没有改变。使用mod_headers和mod_substitute(或等效项)在反向代理中进行必要的更改。
就个人而言,我总是选择1,因为它更简单,更快捷,更容易且更不容易出错。当他们坚持要求他们必须在反向代理中更改上下文路径时,我花了好几天帮助客户调试问题。
为什么会这样?
当反向代理中的上下文路径发生变化时,有许多地方可能需要更改该路径:
ProxyPass处理1
ProxyPassReverse处理位置,内容位置和URI标头(2)
ProxyPassReverseCookiePath处理5
mod_proxy不处理案例4或案例5,因为这很难做到。您最终必须根据具体情况编写一些非常仔细的正则表达式,以获得所需的结果。
我怀疑flashAttributes正在使用包含路径的自定义HTTP标头,这就是它们不起作用的原因。会话将起作用,因为它通常由会话cookie管理,并且您已配置ProxyPassReverseCookiePath。
答案 1 :(得分:0)
我知道这个问题很老了。
但是有一种方法可以通过代理和Spring Flash属性来解决这种情况。
我为FlashMapManager创建了一个自定义实现,覆盖了isFlashMapForRequest方法。
<bean id="flashMapManager" class="my.package.CustomSessionFlashMapManager" >
</bean>
并声明一个bean:
function cds() {
cd $1; ls -lart
current_dir=$PWD
venv_dir="$current_dir/venv"
if [ -d $venv_dir ];
then
venv_activate="$venv_dir/bin/activate"
echo "Directory has corresponding virtual environment.."
echo "Sourcing $venv_activate.."
source $venv_activate
else
deactivate
fi
}
不幸的是,Spring使用请求路径来存储和检索Flash属性。因此,重定向时的/ someUrl在代理后变为/ myApp / someURL。