Spring 弹簧&x27;s flashAttributes don';不能在反向代理后工作
我在尝试使重定向属性的flashAttributes工作时遇到问题。 我已经在Tomcat7.0上安装了一个用SpringMVC构建的网站,并使用ApacheModu代理和ajp创建了一个反向代理 中也描述了我面临的问题,但这里提供的答案并不适用于我的情况(我使用的是Tomcat的一个实例) 这是我用于测试目的的控制器的一个片段:Spring 弹簧&x27;s flashAttributes don';不能在反向代理后工作,spring,tomcat,spring-mvc,redirect,proxy,Spring,Tomcat,Spring Mvc,Redirect,Proxy,我在尝试使重定向属性的flashAttributes工作时遇到问题。 我已经在Tomcat7.0上安装了一个用SpringMVC构建的网站,并使用ApacheModu代理和ajp创建了一个反向代理 中也描述了我面临的问题,但这里提供的答案并不适用于我的情况(我使用的是Tomcat的一个实例) 这是我用于测试目的的控制器的一个片段: @RequestMapping(value = "/land", method = RequestMethod.GET) public String land
@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_代理背后的:
Flash消息:
会话消息:会话消息 为什么通过代理访问网站时没有flash消息 我检查了和的代码,但是没有足够的信息(显然逻辑是在别处实现的) 注意:我总是可以回到会话属性来实现我的目标,但是对于那些在反向代理后面使用Tomcat的人来说,这个问题已经足够有趣了
代理配置(代码段):
ServerName dev.myapp.lan
ProxyPass/ajp://localhost:8009/MyApp/
ProxyPassReverseCookiePath/MyApp/
ProxyPassReverseCokieDomain本地主机MyApp
ErrorLog/var/log/apache2/phonebook-error.log
日志级别警告
CustomLog/var/log/apache2/phonebook-access.log组合
TIA。更改反向代理中的上下文路径通常会导致问题。假设这是一个问题,你有两个选择
我怀疑flashAttributes使用的是包含路径的自定义HTTP头,这就是它们无法工作的原因。会话将按照会话cookie通常管理的方式工作,并且您已经配置了ProxyPassReverseCookiePath。我知道这个问题已经很老了 但是有一种方法可以通过代理和Spring Flash属性来解决这个问题 我为FlashMapManager创建了一个定制的实现,覆盖了isFlashMapForRequest方法
public class CustomSessionFlashMapManager extends SessionFlashMapManager {
@Override
protected boolean isFlashMapForRequest(FlashMap flashMap, HttpServletRequest request) {
String prefixApplicationName = "myApp/";
String expectedPath = flashMap.getTargetRequestPath();
if (expectedPath.startsWith(prefixApplicationName)) {
expectedPath = expectedPath.replace(prefixApplicationName, "");
}
if (expectedPath != null) {
String requestUri = getUrlPathHelper().getOriginatingRequestUri(request);
requestUri = requestUri.replace(prefixApplicationName, "");
if (!requestUri.equals(expectedPath) && !requestUri.equals(expectedPath + "/")) {
return false;
}
}
MultiValueMap<String, String> actualParams = getOriginatingRequestParams(request);
MultiValueMap<String, String> expectedParams = flashMap.getTargetRequestParams();
for (String expectedName : expectedParams.keySet()) {
List<String> actualValues = actualParams.get(expectedName);
if (actualValues == null) {
return false;
}
for (String expectedValue : expectedParams.get(expectedName)) {
if (!actualValues.contains(expectedValue)) {
return false;
}
}
}
return true;
}
private MultiValueMap<String, String> getOriginatingRequestParams(HttpServletRequest request) {
String query = getUrlPathHelper().getOriginatingQueryString(request);
return ServletUriComponentsBuilder.fromPath("/").query(query).build().getQueryParams();
}
}
公共类CustomSessionFlashMapManager扩展SessionFlashMapManager{
@凌驾
受保护的布尔值isFlashMapForRequest(FlashMap FlashMap、HttpServletRequest请求){
字符串前缀applicationname=“myApp/”;
字符串expectedPath=flashMap.getTargetRequestPath();
if(expectedPath.startsWith(前缀applicationname)){
expectedPath=expectedPath.replace(前缀applicationName,“”);
}
if(expectedPath!=null){
字符串requestUri=getUrlPathHelper().getOriginatingRequestUri(请求);
requestUri=requestUri.replace(前缀applicationname,“”);
如果(!requestUri.equals(expectedPath)和&!requestUri.equals(expectedPath+“/”){
返回false;
}
}
多值映射actualParams=getOriginatingRequestParams(请求);
多值映射expectedParams=flashMap.getTargetRequestParams();
for(字符串expectedName:expectedParams.keySet()){
列出actualValues=actualParams.get(expectedName);
if(实际值==null){
返回false;
}
for(字符串expectedValue:expectedParams.get(expectedName)){
如果(!ActualValue.contains(expectedValue)){
返回false;
}
}
}
返回true;
}
私有多值映射getOriginatingRequestParams(HttpServletRequest请求){
字符串查询=getUrlPathHelper().getOriginatingQueryString(请求);
返回ServletUriComponentsBuilder.fromPath(“/”).query(query.build().getQueryParams();
}
}
并声明一个bean:
<bean id="flashMapManager" class="my.package.CustomSessionFlashMapManager" >
</bean>
与dimi sad一样,Spring使用请求路径来存储和检索flash属性。所以,重定向时的/someUrl在代理之后变成了/myApp/someUrl。如何配置反向代理。至少,我们需要查看ProxyPass指令,理想情况下还需要查看所有代理配置。@MarkThomas我用我正在使用的apache配置中的一个片段更新了我的问题。请让我知道这是否足够。非常感谢。确实是换了衣服
<bean id="flashMapManager" class="my.package.CustomSessionFlashMapManager" >
</bean>