17、Cookie和HttpSeesion

一、会话概述

会话可简单理解为:用户开一个浏览器,点击多个超链接,访问服务器多个web资源,然后关闭浏览器,整个过程称之为一个会话

会话能保持各个客户端自己的数据

保存会话数据的两种技术:Cookie、HttpSession

二、Cookie

Cookie是客户端技术,程序把每个用户的数据以cookie的形式写给用户各自的浏览器。当用户使用浏览器再去访问服务器中的web资源时,就会带着各自的数据去。这样,web资源处理的就是用户各自的数据了

 

1、 Cookie 方法

javax.servlet.http.Cookie类用于创建一个Cookie,response接口中定义了一个addCookie方法,它用于在其响应头中增加一个相应的Set-Cookie头字段。 同样,request接口中也定义了一个getCookies方法,它用于获取客户端提交的Cookie

2、Cookie 细节

(1)一个Cookie只能标识一种信息(String),它至少含有一个标识该信息的名称(NAME)和设置值(VALUE)
(2)一个WEB站点可以给一个WEB浏览器发送多个Cookie,一个WEB浏览器也可以存储多个WEB站点提供的Cookie。
(3)创建一个 cookie,cookie 是 servlet 发送到 Web 浏览器的少量信息,这些信息由浏览器保存,然后发送回服务器。cookie 的值可以唯一地标识客户端,因此 cookie 常用于会话管理。
(4)一个 cookie 拥有一个名称、一个值和一些可选属性,比如注释、路径和域限定符、最大生存时间和版本号。一些 Web 浏览器在处理可选属性方面存在 bug,因此有节制地使用这些属性可提高 servlet 的互操作性。
(5)servlet 通过使用 HttpServletResponse#addCookie 方法将 cookie 发送到浏览器,该方法将字段添加到 HTTP 响应头,以便一次一个地将 cookie 发送到浏览器。浏览器应该支持每台 Web 服务器有 20 个 cookie,总共有 300 个 cookie,并且可能将每个 cookie 的大小限定为 4 KB。
(6)浏览器通过向 HTTP 请求头添加字段将 cookie 返回给 servlet。服务器可使用 HttpServletRequest#getCookies 方法从请求中获取 cookie。一些 cookie 可能有相同的名称,但却有不同的路径属性。
(7)如果创建了一个cookie,并将他发送到浏览器,默认情况下它是一个会话级别的cookie(即存储在浏览器的内存中),用户退出浏览器之后即被删除。若希望浏览器将该cookie存储在磁盘上,则需要使用maxAge,并给出一个以秒为单位的时间。将最大时效设为0则是命令浏览器删除该cookie。
注意,删除cookie时,path必须一致,否则不会删除
 

3、属性

name: 名称不能唯一确定一个cookie。路径可能不同
value: 不能存中文
path: 默认是写入cookie那个应用的访问路径
如: http://localhost:8080/day10/servlet/cookieDemo1
Path: / day10/servlet/
当客户端访问服务器其它资源时,根据访问路径来决定是否带着cookie到服务器,当访问的路径是以cookie中path开头的路径,就带cookie,否则就不带
maxAge: cookie的保存时间。默认是-1(表示保存在浏览器的内存中)
负数:cookie存在浏览器的内存中。
0:删除。路径要保持一致,否则会删错了。
正数:缓存(持久化到磁盘中)的时间。
1 Cookie cookie = new Cookie();  // 创建
2 resquest.getCookies();  // 从浏览器获取Cookies
3 response.addCookie();  // 写回浏览器

 

 1 // 保存客户端的最后访问时间
 2 public void doGet(HttpServletRequest request, HttpServletResponse response)
 3         throws ServletException, IOException {
 4     
 5     response.setContentType("text/html;charset=UTF-8");
 6     
 7     PrintWriter out = response.getWriter();
 8     
 9     // 保存客户端的最后访问时间
10     Cookie[] cookies = request.getCookies();  // 获取所有Cookie
11     for (int i = 0; cookies!=null&&i < cookies.length; i++) {  
12         if("lastAccessTime".equals(cookies[i].getName())) {  // 判断当前Cookie的name是否想要的Cookie
13             long l = Long.parseLong(cookies[i].getValue());  // 是想要的Cookie则取出value
14             out.write("最后的访问时间:"+new Date(l).toLocaleString());
15         }
16     }
17     
18     // 创建Cookie
19     Cookie cookie = new Cookie("lastAccessTime", System.currentTimeMillis()+"");  // lastAccessTime为当前系统时间
20     
21     // 设置保存的时间
22     cookie.setMaxAge(60*5);
23     // 设置路径,其下应用都可以相互访问cookie
24     cookie.setPath(request.getContextPath());  // 效果和setPath("/")一样,都是当前在服务器上的应用的根路径,/Cookie
25 //        cookie.setPath("/");
26     
27     // 把Cookie信息写回客户端
28     response.addCookie(cookie);
29 }

 

 1 // 删除Cookie,覆盖相当于删除
 2 public void doGet(HttpServletRequest request, HttpServletResponse response)
 3         throws ServletException, IOException {
 4     // 创建Cookie
 5     Cookie cookie = new Cookie("lastAccessTime", "");  
 6             
 7     cookie.setPath(request.getContextPath());  // 设置Cookie的路径,否则可能删错
 8     // 设置保存的时间
 9     cookie.setMaxAge(0);  // 相当于删除
10     
11     response.addCookie(cookie);  // 将cookie写回缓存
12 }
out.print("<a href='"+request.getContextPath()+"/servlet/clear'>clear</a>");  // clear跳转到clear Servlet

 

 1 // 记住用户名
 2 public class LoginServlet extends HttpServlet {
 3 
 4     public void doGet(HttpServletRequest request, HttpServletResponse response)
 5             throws ServletException, IOException {
 6         
 7         response.setContentType("text/html;charset=UTF-8");
 8         PrintWriter out = response.getWriter();
 9         String userName = "";  // 第一次为空
10         String checked = "";
11         
12         // 得到客户端保存的数据
13         Cookie[] cookies = request.getCookies();
14         for (int i = 0; cookies!=null && i < cookies.length; i++) {
15             if("userName".equals(cookies[i].getName())) {
16                 userName = cookies[i].getValue();
17                 checked = "checked='checked'";
18             }
19         }
20         
21         // 绘制表单并提交表单
22         out.write("<form action='"+request.getContextPath()+"/servlet/dologin' method='post'>");
23         out.write("用户名 :<input type='text' name='userName' value='"+userName+"'/><br/>");
24         out.write("密码 :<input type='password' name='pwd' /><br/>");
25         out.write("<input type='checkbox' name='remember' "+checked+"/>记住用户名<br/>");
26         out.write("<input type='submit'  value='登录'/><br/>");
27         out.write("</form>");
28     }
29 }
 1 // 记住用户名登录操作
 2 public class DoLogin extends HttpServlet {
 3 
 4     public void doGet(HttpServletRequest request, HttpServletResponse response)
 5             throws ServletException, IOException {
 6         
 7         // 设置编解码方式
 8         request.setCharacterEncoding("UTF-8");
 9         response.setContentType("text/html;charset=UTF-8");
10         
11         PrintWriter out = response.getWriter();  // 输出流,和OutputStream一样,但是可以接受不同的类型数据写出
12         
13         // 获取表单数据
14         String userName = request.getParameter("userName");
15         String pwd = request.getParameter("pwd");
16         String remember = request.getParameter("remember");
17         
18         Cookie cookie = new Cookie("userName", userName);
19         cookie.setPath("/");  // 设置在当前应用下
20         // 处理业务逻辑
21         // 分发转向
22         if("tom".equals(userName) && "123".equals(pwd)) {
23             if(remember!=null) {  // 勾选记住密码,没勾选就是null
24                 cookie.setMaxAge(Integer.MAX_VALUE);  // 永久保存
25             } else {
26                 cookie.setMaxAge(0);  // 不勾选删除Cookie
27             }
28             response.addCookie(cookie);  // 将Cookie写回到客户端
29             out.write("登录成功");  // 输出到页面
30         } else {
31             out.write("登录失败");
32             // 登录失败后2s重新登录
33             response.setHeader("refresh", "2,url="+request.getContextPath()+"/servlet/login"); 
34         }
35     }
36 }

 

三、HttpSession

Session是服务器端技术,利用这个技术,服务器在运行时可以为每一个用户的浏览器创建一个其独享的HttpSession对象,由于session为用户浏览器独享,所以用户在访问服务器的web资源时,可以把各自的数据放在各自的session中,当用户再去访问服务器中的其它web资源时,其它web资源再从用户各自的session中取出数据为用户服务。
 

1、Session和Cookie的主要区别

(1)Cookie是把用户的数据写给用户的浏览器。
(2)Session技术把用户的数据写到用户独占的session中。
(3)Session对象由服务器创建,开发人员可以调用request对象的getSession方法得到session对象。
 
 
它也是一个域对象: session servletContext request
同一个会话下 ,可以使一个应用的 多个资源共享数据
cookie客户端技术,只能存字符串,不存密码等敏感信息 。HttpSession 服务器端的技术,它可以存对象,可以存密码,通过id区分不同用户 。
 
request < session < servletContext
request:一次请求有效,service之前创建,结束之后销毁
session:一次会话有效,第一次访问服务器资源创建,会话结束销毁,当前应用的的多个servlet可以共享
servlet:整个应用有效,多个用户可以访问
 
 

2、常用方法

把数据保存在HttpSession对象中,该对象也是一个域对象。
1 void setAttribute(String name,Object value);
2 Object getAttribute(String name);
3 void removeAttribute(String name);
4 HttpSession.getId():
5 setMaxInactiveInterval(int interval)   // 设置session的存活时间,默认30分钟
6 invalidate()  // 使此会话无效,退出登录

 

3、getSession()内部执行原理(常用)

HttpSession session = request.getSession();
1、获取名称为JSESSIONID的cookie的值。
2、没有这样的cookie,创建一个新的HttpSession对象,分配一个唯一的SessionID,并且向客户端写了一个名字为JSESSIONID=sessionID的cookie
3、有这样的Cookie,获取cookie的值(即HttpSession对象的值),从服务器的内存中根据ID找那个HttpSession对象:
找到了:取出继续为你服务。
找不到:从2开始。(超过30min)
 
HttpSession request.getSession(boolean create);
参数:
true:和getSession()功能一样。
false:根据客户端JSESSIONID的cookie的值,找对应的HttpSession对象,找不到返回null(不会创建新的,只是查询)。
 
session四种死法:
1、过了默认时间
2、强制销毁
3、设置最大存活时间
4、在web.xml中设置

 

 4、客户端禁用Cookie后的会话数据保存问题

客户端禁用cookie:浏览器永远不会向服务器发送cookie的请求消息头
 
解决方案:
方案一:在主页上给出提示:请不要禁用您的cookie
方案二:URL重写。必须对网站的所有地址都重写。
 
http://url--->http://url;JSESSIONID=111
response.encodeURL(String url);
看浏览器有没有发送cookie请求消息头,没有就重写URL,有就不重写。
request.getSession();必须写
 
 
 
 
 
 
 
posted @ 2016-12-07 00:47  十年英雄梦  阅读(236)  评论(0编辑  收藏  举报