1

我正在阅读有关该HttpSession.isNew()方法的“Head First JSP And Servlets”。有一种我无法理解的奇怪行为。

这是一些示例代码。

import java.io.IOException;
import java.io.PrintWriter;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

public class TestSessionServlet extends HttpServlet {
  @Override
  protected void doGet(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse)
      throws ServletException, IOException {
     doPost(httpServletRequest,httpServletResponse);
  }

  @Override
  protected void doPost(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse)
      throws ServletException, IOException {
    httpServletResponse.setContentType("text/html");
    PrintWriter out = httpServletResponse.getWriter();

    HttpSession session = httpServletRequest.getSession();

    if(session.isNew()){
      out.println("this is a new session");
    }  else{
      out.println("Welcome Back Ben:");
    }
  }
}

现在,当我在 Tomcat 中部署应用程序并第一次点击 servlet 时,if它没有转到块,而是转到else块。当我第一次从另一个浏览器访问同一个 servlet 时,它会进入if块。

当应用程序刚刚启动并且我第一次点击 servlet 时,它不应该转到if块而不是else? 有人可以详细说明一下吗?

4

2 回答 2

2

在访问您的 servlet 之前清除浏览器的 cookie(在大多数浏览器上为 CTRL+SHIFT+DEL)。清除 cookie 后,第一次访问时会话应该是新的。

这个想法是这样的。HTTP 是一种无状态协议,这意味着每个请求都与之前的任何请求无关。这适用于诸如网站之类的东西,这些网站只向请求它们的人提供页面,但对于需要跟踪与不同用户的复杂交互的 Web 应用程序来说却是一个问题。

会话是一种存储数据的方法,用于保留有关用户与应用程序交互的信息。但是,由于 HTTP 是无状态的,服务器如何知道哪个请求属于哪个用户?

在无状态协议中,请求必须包含服务器处理该请求所需的所有数据。这还包括客户端 cookie(如果有)。cookie 包含称为“会话 ID”的标识令牌(在 Java 中是JSESSIONID)。

您将获得一个具有以下执行流程的“会话 ID”(该流程有点复杂,因为它需要考虑过期的会话或禁用 cookie 的浏览器,但这是一般的想法):

  • 浏览器向应用程序发出第一个请求。此时客户端不存在 cookie,因此不会随请求发送 cookie;
  • 应用程序在请求中查找“会话 ID”。没有找到,因此应用程序知道这是来自新客户端的请求。应用程序创建一个新会话并生成一个“会话 ID”来标识该会话;
  • 应用程序响应客户端并在响应中的 cookie 中包含“会话 ID”;
  • 浏览器向应用程序发出另一个请求。此时存在 Cookie,浏览器将其发送回应用程序;
  • 应用程序在请求中查找“会话 ID”。这次找到了,因此服务器知道这是来自旧客户端的请求,并根据“会话 ID”中的值查找现有会话。

这就是为什么当您使用新浏览器访问您的 servlet 时应用程序显示正确消息以及使用另一个浏览器时它显示错误消息的原因。另一个浏览器可能有来自您之前对应用程序发出的请求的 cookie。

服务器重新启动并不总是意味着会话被破坏。Tomcat 在重新启动之间序列化/反序列化会话,因此您认为可能不再存在的会话可能仍然存在于服务器上并与现有 cookie 相关联。清除浏览器的 cookie 意味着一个新的请求,其中没有会话信息。

于 2013-10-20T19:55:52.017 回答
0

我遇到了和你完全相同的问题。但是,在我清除 cookie 后,我得到了一个新的会话 ID,但 isNew() 方法仍然始终返回 false。因此,我阅读了有关该方法的文档,我认为它为该主题提供了一些新的启示。

是新的

public boolean isNew()

如果客户端还不知道会话或者客户端选择不加入会话,则返回 true。例如,如果服务器仅使用基于 cookie 的会话,而客户端已禁用 cookie,则每次请求都会有一个新会话。

返回: true如果服务器已创建会话,但客户端尚未加入

https://tomcat.apache.org/tomcat-5.5-doc/servletapi/javax/servlet/http/HttpSession.html

于 2017-12-03T13:43:06.083 回答