以前,servlet使用response.sendRedirect("pages/my_page.jsp?foo=bar");
没有问题。可以在重定向到的后续页面中检索会话属性。
目前,我正在改变发送请求的方式。最初,Javascript使用myForm.submit();
,但我现在已将其更改为jQuery.ajax("my_page.jsp?foo=bar", {...});
。然后,servlet在JSON响应中包含一个URL而不是response.sendRedirect()
,在success
函数中,我使用window.location.replace(url);
导航到新页面。但是,无法在后续页面中提取已保存的会话属性。
我通过在JSP页面中插入<%= session.getId() %>
来比较会话ID。他们是一样的。这里的问题是session.getAttribute("myAttribute_1")
在重定向到的页面中返回null
。
我不确定这是否重要,但我实际上是在使用多个JSP页面执行此任务:
A.jsp --- (redirect) ---> B.jsp --- (redirect) ---> C.jsp
在这种情况下,如何在C.jsp
?
以下是我用来保存会话属性的代码段。
public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
HttpSession session = request.getSession(true);
response.setContentType("application/json");
CustomObject customObject = new CustomObject();
// ...
session.setAttribute("myAttribute_1", customObject);
PrintWriter writer = response.getWriter();
JsonObject json = new JsonObject();
Gson gson = new GsonBuilder().setPrettyPrinting().create();
json.addProperty("url", "next_page.jsp?foo=bar");
writer.println(gson.toJson(json));
writer.close();
}
以下是重定向的代码段。
function redirectHandler(data, currentUrl) {
if (data && data.hasOwnProperty('url')) {
var redirectUrl = data.url;
jQuery.get(redirectUrl).done(function(response) {
redirectHandler(response, redirectUrl);
});
} else {
window.location.replace(currentUrl);
}
}
function sendFormData(method, url, form) {
jQuery.ajax(url, {
'method': method,
'data': parseData(jQuery(form).serializeArray()),
'success': function(data) {
redirectHandler(data, window.location.href);
}
});
}
我已经恢复使用我的servlet中的response.sendRedirect("pages/my_page.jsp?foo=bar")
。
在客户端,jQuery.ajax()
被删除,功能sendFormData()
更新如下。
function sendFormData(form) {
var data = parseData(jQuery(form).serializeArray());
var f = document.createElement('form');
for (var key in data) {
jQuery('<input>').attr({
'type': 'hidden',
'name': key,
'value': data[key]
}).appendTo(f);
}
f.setAttribute('method', form.getAttribute('method'));
f.setAttribute('action', form.getAttribute('action'));
f.submit();
}
每当我想提交表单时,都会附加click
事件处理程序。它将调用sendFormData(myOriginalForm);
而不是myOriginalForm.submit();
,因为我需要自定义要发送的数据。
只有应用这些简单的更改,一切都会再次运作。
不过,我正在寻找关于这种奇怪行为的解释。
答案 0 :(得分:3)
您是否尝试过不同形式的Javascript重定向?
推荐的方法是:
window.location.href=currentUrl;
根据此article,使用window.location.replace
将替换当前会话。
答案 1 :(得分:2)
HTTP请求是无状态的,会话通过不同的方式放在HTTP之上,如
http://host:port/path;session_id=12345
)客户有责任确保他们通过服务器预期的方式参与会话。当使用Java Servlet API实现服务器时,它是 jsessionid cookie或具有相同名称的查询参数附加到URL,用于标识会话ID。
如果客户端不支持cookie,则必须使用Java Servlet API重定向到
由HttpServletResponse.encodeRedirectURL(String url)
创建的网址。
要从servlet重定向,请使用HttpServletResponse.sendRedirect(String url);
。
使用HTTP重定向标准对服务器进行响应将简化您的设计。 Jquery 确实实施了这些标准,因此将来自服务器的 HTTP 301 和 302 响应视为ilustrated here,因此没有重定向逻辑客户方应该是必需的。
您的客户端 jquery ,当后续请求发送到同一域时,其ajax实现将尊重并重播为任何给定域设置的Cookie。
如果您要重定向到其他域, jquery 可以使用 CORS 会话,请在您的请求中添加xhrFields
:
$.ajax({
url: a_cross_domain_url,
xhrFields: {
withCredentials: true
}
});