【问题标题】:JSP::Confused with the session objectsJSP::与会话对象混淆
【发布时间】:2011-03-04 04:50:47
【问题描述】:

我刚开始探索 Java Servlet 和 JSP,对会话对象有点困惑。在一个 servlet 里面我有这个:

public class SampleServlet extends HttpServlet {

    public void doPost(HttpServletRequest request, HttpServletResponse response)
    throws IOException {

        HttpSession session = request.getSession(true);
        session.setAttribute("_session", "_value");
                response.sendRedirect("page2.jsp");         
        }
}

现在,在 page2.jsp 中,也有一个会话对象,但是当我这样做时

<%
out.print(session.getAttribute("_session"))
%>

它似乎没有得到值(好像没有设置)。我尝试将布尔属性设置为 true,但在 jsp 页面中它返回 false。有人可以告诉我这样做的正确方法吗?至于我想要做什么,我想分享一些会话变量。

【问题讨论】:

  • 您确定您的浏览器配置为支持cookies吗?重定向返回到客户端,然后返回到服务器。也许cookie丢失了。
  • 您需要启用 cookie - 您确定要启用吗?
  • @Eyal 和@OpenSource:是的。我的浏览器支持 cookie。我正在尝试下面给出的一些建议。会回来的。
  • 在以后的问题中,您应该提前提及您正在使用 GAE,它使事情变得足够不同,在许多情况下都会有所作为。

标签: java google-app-engine jsp servlets


【解决方案1】:

使用 request.getRequestDispatcher().forward() 代替 response.sendRedirect();

所以你的代码是:

 HttpSession session = request.getSession(true);
 session.setAttribute("_session", "_value");
 request.getRequestDispatcher("page2.jsp").forward();     

基本上,response.sendRedirect() 不会保留会话信息,所以当 jsp 获取它时它不存在。 request.forward() 确实保留了会话。

http://www.coderanch.com/t/170618/java-Web-Component-SCWCD/certification/sendRedirect-Vs-requestdispatcher-forward

【讨论】:

  • 最后一行在语法上无效,他正在设置会话属性,所以它应该在重定向请求中。
  • 太棒了!谢谢...现在可以使用了...不过,我不得不将 forward 更改为 forward(request, response)
  • @Legend:这可能取决于容器。您的初始方法在此处的 Tomcat 6 和 Glassfish 3 上都可以正常工作。我测试了它。这将是 Google Appengine 使用的容器中的错误。
  • @BalusC:感谢您的澄清。我会向 Google 提出错误报告,因为我可以重现它。
【解决方案2】:

假设您的容器支持它,请使用EL

Java端:

HttpSession session  = request.getSession(true);
session.setAttribute("foo", "bar");

JSP 端:

<html>
    ...
    <body>
        ...
        <p>${foo}</p>
        ...
    </body>
</html>

这会给你一个包含字符串bar的段落。

【讨论】:

  • EL+1。刚开始听到一些 Java 端技术 :)
  • @skaffman - 原始问题(重定向不保留会话信息)是特定于 GAE 的吗?当我想通过重定向保留信息时,我实际上使用了会话属性(与请求属性相比),使用 JBoss+Tomcat。
【解决方案3】:

虽然不是最好的方法(我宁愿使用 EL ${_session} 而不是 scriptlet),但这应该可以正常工作。你的问题出在其他地方。您是否正在运行您认为正在运行的代码?你是如何编译和部署代码的?你没有从给定的例子中删减太多吗?会话即依赖于域和上下文,如果您重定向到不同的域和/或上下文,则将创建一个新会话。此外,会话由 cookie 支持,浏览器是否启用了 cookie?否则,您必须使用 HttpServletResponse#encodeRedirectURL() 将会话标识符附加到重定向 URL。

response.sendRedirect(response.encodeRedirectURL("page2.jsp"));

更新:要调试它是否真的是 same 会话,请在 servlet 中执行:

System.out.println("Session ID: " + session.getId());

在 JSP 中:

<p>Session ID: ${pageContext.session.id}</p>

另外安装像FirebugNet 面板这样的HTTP 标头跟踪器可能会带来新的见解。 HTTP 响应应包含带有会话 ID 的 Set-Cookie 标头,随后的 HTTP 请求应包含具有相同 cookie 名称/值的 Cookie 标头,通常为 JSESSIONID,带有像 this screenshot 一样的长十六进制值。


更新 2: 因为我很惊讶,因为前锋显然解决了这个问题,所以我尝试在 Tomcat 6 和 Glassfish 3 上重现此问题,但这种方法在两台服务器上都能完美运行。所以我怀疑 Appengine 使用的容器中存在错误,它在重定向期间没有正确设置 cookie。

作为证据,这里有一个屏幕证明 Glassfish 正在通过 Set-Cookie 设置 cookie 并且 通过 Location 触发重定向:

【讨论】:

  • 我正在使用 Google App Engine 框架。在 Eclipse 创建的项目中编写一些 servlet 和 jsp 文件。
猜你喜欢
  • 2015-01-17
  • 2012-05-21
  • 2010-11-05
  • 1970-01-01
  • 1970-01-01
  • 2015-06-26
  • 1970-01-01
  • 2011-10-28
  • 2013-04-12
相关资源
最近更新 更多