Cookie和Session总结
Cookie概述
Cookie是什么?
Cookie是一小段文本信息,伴随着用户请求和页面在Web服务器和浏览器之间传递.Cookie包含每次用户访问站点时Web应用程序都可以读取的信息.
为什么需要Cookie?
因为HTTP协议是无状态的,对于一个浏览器发出的多次请求,WEB服务器无法区分是不是来源于同一个浏览器.所以,需要额外的数据用于维护会话.Cookie正是这样的一段随HTTP请求一起被传递的额外数据.
Cookie能做什么?
Cookie只是一段文本,所以它只能保存字符串.而且浏览器对它有大小限制以及它会随着每次请求被发送到服务器,所以应该保证它不要太大.Cookie的内容也是明文保存的,有些浏览器提供界面修改,所以,不适合保存重要的或者涉及隐私的内容
每个浏览器都有一个保存Cookie的文件,这个Cookie是保存在客户端的..我们访问一个网站的时候返回的不仅是html页面,同时返回的还有一个文件:cookie.所以,每当我们用浏览器访问一个页面时,会先从cookie里面遍历,看有没有,如果有就会带上.
可以使用Cookie
的setXXX方法来设定一些相应的值
setName(String name)/getName()
setValue(String value)/getValue()
setMaxAge(int age)/getMaxAge()
利用HttpServletResponse的addCookie(Cookie)方法将它设置到客户端
利用HttpServletRequest的getCookies()方法来读取客户端的所有Cookie,返回一个Cookie数组
设置Cookie
SetCookies.java
读取Cookie
ShowCookies.java
通过下面这段代码设置Cookie:
public class _06_ServletCookie extends HttpServlet { private static final long serialVersionUID = 1L; @Override protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { for (int i = 0; i < 6; i++) { Cookie cookie = new Cookie("Session-Cookie-" + i, "Cookie-Value:" + i); resp.addCookie(cookie); //只有用 javax.servlet.http.Cookie.setMaxAge() 函数设置了生命周期的cookie才会写进客户端电脑的硬盘中 //这种的只要不过期,cookie就会存在 //如果没有设置生命周期的,只会保存在浏览器域的内存中,浏览器一关闭,就会被删除 Cookie cookie2 = new Cookie("Persistent-Cookie-" + i, "Cookie-Value-P"+i); cookie2.setMaxAge(3000); //通过 javax.servlet.http.HttpServletResponse.addCookie();当时把cookie发送给客户端 resp.addCookie(cookie2); } resp.setContentType("text/html;charset=utf-8"); PrintWriter out = resp.getWriter(); String title = "Setting Cookie"; out.println( "<html><head><title></title></head>" + "<body>\n" + "<h1 align='center'>" + title + "</h1>\n" + "To See them,visit the\n" + "<a href='_07_ShowCookies'>\n" + "<CODE>ShowCookie</CODE>Servlet</a>" + "</body></html>"); } @Override protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { doPost(req, resp); } }
通过下面这段代码来显示我们设置的Cookie信息
public class _07_ShowCookies extends HttpServlet { @Override protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { resp.setContentType("text/html;charset=utf-8"); PrintWriter out = resp.getWriter(); String title = "Active Cookie"; out.println( "<html><head><title>接受客户端Cookie</title></head>" + "<body><h1>"+title+"</h1>" + "<table align='center' border=1>\n" + "<tr><th>Cookie Name</th><th>Cookie value</th></tr>" ); Cookie[] cookies = req.getCookies(); if(cookies != null){ Cookie cookie; for (int i = 0; i < cookies.length; i++) { cookie = cookies[i]; out.println( "<tr>\n" + "<td>" + cookie.getName() + "</td>" + "<td>" + cookie.getValue() + "</td></tr>\n" ); } out.println("</table></body></html>"); }else{ out.println("<tr><td colspan='2'>没有本网站的Cookie</td></tr>"); out.println("</table></body></html>"); } } @Override protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { doGet(req, resp); } }
运行之前我们先看看浏览器保存的Cookie,由于我之前清空了Cookie,所以这里显示没有保存Cookie
然后我们运行代码,先运行_06_ServletCookie,设置Cookie,
再看看浏览器保存的Cookie
然后点击_06_ServletCookie中的超链接,我们设置的Cookie全部显示出来了
在_06_ServletCookie中一共设置了2种Cookie,一种有时间限制,一个没有设置时间.
这里关闭浏览器,然后直接进入_07_ShowCookies中
"
通过结果我们可以看出,没有设置时间的Cookie没有了,而设置时间的Cookie依然存在.所以如果Cookie没有设置时间限制的话,浏览器一关闭,保存的Cookie会自动删除
如果不运行_06_ServletCookie直接运行_07_ShowCookies呢?
显示没有保存的Cookie,因为没有设置Cookie
Session
session机制是一种服务器端的机制,服务器使用一种类似于散列表的结构来保存信息.
当程序需要为某个客户端请求创建一个session的时候,服务器首先检查这个客户端的请求里是否包含了一个session表示,成为sessionid,如果已包含一个sessionid则说明以前已经为此客户端创建过session,服务器就按照sessionid把这个session检索出来使用,如果客户端请求不包含sessionid,则为此客户端创建一个session并且生成一个与此session相关联的sessionid,sessionid的值应该是一个既不会重复,又不容易被找到规律以仿造的字符串,这个sessionid将被在本次响应中返回给客户端
如果浏览器支持Cookie,创建Session的时候会把SessionID保存在Cookie里
如果不支持Cookie,必须自己编程使用URL重写的方法实现Session
public class _08_SetSessionServlet extends HttpServlet { @Override protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { //设置MIME类型为text/html resp.setContentType("text/html;charset=utf-8"); //获取当前的Session,如果没有可以创建 //getSession(),如果为false,没有Session也不会创建 //如果为true:没有Session就会创建一个 HttpSession mySession = req.getSession(true); PrintWriter out = resp.getWriter(); //生成html文档 out.println("<html><head><title>Session Info Servlet</title></head>" + "<body><h3>session information</h3>" + "<b>New Session:</b>" + mySession.isNew() + "</br><b>SessionID:</b>" + mySession.getId() //显示Session的创建时间 + "</br><b>Session Create Time:</b>" + new java.util.Date(mySession.getCreationTime()) //显示Session最后接受的时间 + "</br><b>Session last accessed time:</b>" + new java.util.Date(mySession.getLastAccessedTime()) + "<h3>Request Information</h3>" //返回随客户端请求到来的会话ID.可能与当前的会话ID相同,也可能不同 + "</br><b>Session ID from request:</b>" + req.getRequestedSessionId() //当前的Session ID如果是从Cookie获得,为true + "</br><b>SessionID via Cookie:</b>" + req.isRequestedSessionIdFromCookie() //当前Session ID如果是由URL获得,为true + "</br><b>SessionID via rewrite URL:</b> " + req.isRequestedSessionIdFromURL() //当前客户端的会话ID代表的是有效会话,则返回true.否则(比如,会话过期或根本不存在),返回false + "</br><b>valid SessionID:<b>" + req.isRequestedSessionIdValid() + "<br><a href=" + resp.encodeUrl("_08_SetSessionServlet") + ">refresh</a>" + "</body></html>"); out.close(); } @Override protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { doGet(req, resp); } }
先看看浏览器保存的Cookie,我之前清空了,所以这里为空
运行代码
可以清楚的看到Session
ID的信息.
再看下浏览器保存的Cookie
这里只保存了一个"JSESSIONID",这个相当于一个人的身份证号,通过这个身份证好可以在服务器中找到保存的这个人的各种信息.
刷新一下试试
可以看到 New Session:
Session last
accessed time:
SessionID via Cookie:
valid
SessionID:
这些信息都变了
浏览器设置为不接受Cookie,点refresh刷新:
SessionID via rewrite URL:
这个信息就会变为true
因为我们是通过Cookie中的SessionID浏览上次的网页的.
Session总结
1.服务器的一块内存(存key-value)
2.和客户端窗口对应(子窗口)(独一无二)
3.客户端和服务器有对应的SessionID
4.客户端向服务器端发送SessionID的时候两种方式:
1.cookie(内存cookie)
2.rewriten URL
5.浏览器禁掉cookie,就不能使用session(使用cookie实现的session)
6.如果想安全的使用session(不论客户端是否禁止cookie),只能使用URL重写(大大增加编程负担),所以很多网站要求客户端打开cookie