Session和Cookie的区别

mac2026-01-18  8

以前看过几篇别人讲Session和Cookie的区别的文章,但是大都给人一种语焉不详的感觉。本文从Tomcat自带的例子入手,讲一下Session和Cookie的区别,本文中Session指J2EE中的HttpSession接口,可参看源码;Cookie有两种含义,一种是指rfc6252中定义的一种HTTP头,另外一种是指J2EE中的Cookie接口。

HttpSession接口

这个接口是J2EE中实现保存跟会话相关的值的机制,具体说就是服务器为本次连接生成了一个唯一对象,这个对象可以保存一些值,如果从后面的HTTP连接中可以获取到这个对象,那么说明这个连接和前面的连接属于同一个会话,也就可以获取到保存的值。 下面我们看一段Tomcat中的示例代码

public class SessionExample extends HttpServlet { public void doGet(HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException { response.setContentType("text/html"); PrintWriter out = response.getWriter(); HttpSession session = request.getSession(true); // print session info Date created = new Date(session.getCreationTime()); Date accessed = new Date(session.getLastAccessedTime()); out.println("ID " + session.getId()); out.println("Created: " + created); out.println("Last Accessed: " + accessed);

这段代码会为首次连接生成一个HttpSession对象,此对象唯一,以后的连接如果能证明它的HttpSession也是这个HttpSession对象,那么说明它跟本次连接属于同一会话。

到这里感觉似乎一切都讲得通,但是我们仔细思考一下的话就会想到一个问题,服务器是怎么知道下一次连接和本次连接属于同一个会话的,服务器需要告诉浏览器咱们这次的连接我生成了什么样的HttpSession,浏览器在下一次连接中也需要告诉服务器我这次跟你建立的连接中带着什么样的HttpSession。 这种在服务器和浏览器之间进行会话确认的机制就是Cookie,这里的Cookie指的是HTTP协议中规定的Cookie机制。服务器通过响应头里面的Set-Cookie来设置Cookie,浏览器用请求头里面的Cookie来告诉服务器,咱们前面已经连接过了,你要我在请求里面带着的内容我都没落下。 我们如果第一次打开上述代码生成的页面(路径为http://localhost:8080/examples/servlets/servlet/SessionExample),就会发现响应头里面有这样的内容

Set-Cookie: JSESSIONID=908A49239490E6FF50919EAF2F4A84B0; Path=/examples; HttpOnly

我们在第二次的连接中,就会发现请求头里面有这样的内容

Cookie: JSESSIONID=908A49239490E6FF50919EAF2F4A84B0;

这样一来服务器就可以用JSESSIONID来找到上次的那个HttpSession对象,也就可以知道它们属于同一个会话。

Cookie

HTTP中的Cookie机制我们前面大概讲过了,这部分我们看J2EE中的Cookie类,Cookie类的属性如下

// // The value of the cookie itself. // private String name; // NAME= ... "$Name" style is reserved private String value; // value of NAME // // Attributes encoded in the header's cookie fields. // private String comment; // ;Comment=VALUE ... describes cookie's use // ;Discard ... implied by maxAge < 0 private String domain; // ;Domain=VALUE ... domain that sees cookie private int maxAge = -1; // ;Max-Age=VALUE ... cookies auto-expire private String path; // ;Path=VALUE ... URLs that see the cookie private boolean secure; // ;Secure ... e.g. use SSL private int version = 0; // ;Version=1 ... means RFC 2109++ style private boolean isHttpOnly = false;

这些属性跟rfc6252中对Cookie的规定基本一致(我承认太懒了没去仔细核对,但是不影响本篇文章的正确性),也就是说,这个类的对象是一个完整的Cookie。 我们看一段Tomcat中的示例代码:

// print out cookies Cookie[] cookies = request.getCookies(); for (int i = 0; i < cookies.length; i++) { Cookie c = cookies[i]; String name = c.getName(); String value = c.getValue(); out.println(name + " = " + value); } // set a cookie String name = request.getParameter("cookieName"); if (name != null && name.length() > 0) { String value = request.getParameter("cookieValue"); Cookie c = new Cookie(name, value); response.addCookie(c); }

我们打开上述代码生成的页面(路径为http://localhost:8080/examples/servlets/servlet/CookieExample),会发现如下内容: Your browser is sending the following cookies: Cookie Name: JSESSIONID Cookie Value: 908A49239490E6FF50919EAF2F4A84B0 这个Cookie Value就是服务器为以前的连接生成的HttpSession的ID,浏览器是通过在连接的Cookie里面放置JSESSIONID来让服务器知道本次连接和前面的连接属于同一会话的。

如果我们用上述两个页面的表单来提交值,会发现设置的Cookie的值会在连接中的头里面,而设置的HttpSession的值不会出现在连接里面,只有服务器打印出来我们才能看到。也就是说Cookie是属于连接的,HttpSession是属于服务器的。

总结

Cookie机制是HTTP协议的一部分,它可以让服务器和浏览器之间的连接带着某些约定的值,服务器是约定的发起方,浏览器是接受方。 HttpSession(也就是我们经常简称的Seesion)是J2EE的一部分,它可以让服务器知道哪些连接属于同一会话,是通过连接的Cookie中的JSESSIONID知道的。

Cookie的概念比Session的概念广一些;一个连接只能有一个Session,但是可以有多个Cookie;

HttpSession session = request.getSession(true); Cookie[] cookies = request.getCookies();

Session的实现借助了Cookie;Cookie属于连接双方,保存在浏览器,Session属于服务器,保存在服务器。

最新回复(0)