我正在阅读关于HttpSession.isNew()
方法的“Head First JSP和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
吗?有人可以详细说明这个吗?
答案 0 :(得分:1)
在访问您的servlet之前清除浏览器的cookie(大多数浏览器上的CTRL + SHIFT + DEL)。清除cookie后,第一次访问时会话应该是新的。
这个想法是这样的。 HTTP是stateless protocol,这意味着每个请求都与先前的任何请求无关。这适用于那些只向任何人提供页面服务的网站,但是对于需要跟踪与不同用户的复杂交互的Web应用程序存在问题。
会话是一种存储数据的方法,用于保留有关用户与应用程序交互的信息。但是,服务器如何知道哪个请求属于哪个用户,因为HTTP是无状态的,服务器的请求都是相同的?
在无状态协议中,请求必须包含服务器处理该请求所需的所有数据。这还包括客户端cookie(如果有)。 Cookie包含一个称为“会话ID”的标识令牌(在Java中是JSESSIONID)。
你得到一个“会话ID”,其中包含以下执行流程(流程有点复杂,因为它需要考虑已禁用cookie的过期会话或浏览器,但这是一般的想法):
这就是为什么当您使用新浏览器访问servlet时应用程序显示正确的消息,以及如果您使用另一个浏览器,它显示错误消息的原因。另一个浏览器可能包含您之前向应用程序发出的请求中的cookie。
重新启动服务器并不总是意味着会话被销毁。 Tomcat在重新启动之间序列化/反序列化会话,因此您认为可能不再存在的会话可能仍然存在于服务器上并与现有cookie相关联。清除浏览器的cookie意味着一个新的请求,其中没有会话信息。
答案 1 :(得分: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