会话技术 Cookie Session

【会话技术】

Ø 什么是会话:用户打开一个浏览器访问页面,访问网站的很多页面,访问完成后将浏览器关闭的过程称为是一次会话.

Ø 常见的会话技术:

* Cookie:将数据保存到客户端浏览器.

* Session:将数据保存到服务器端.

Ø 为什么使用会话技术?

* 私有的数据,购物信息数据保存在会话技术中.

参见图一和图二

Ø 使用会话技术:

Cookie技术的使用】

Ø 向浏览器保存数据:

HttpServletResponse有一个方法:

* void addCookie(Cookie cookie);

Ø 获得浏览器带过来的Cookie:

HttpServletRequest有一个方法:

* Cookie[] getCookies();

Ø 创建一个Cookie对象:

* Cookie(String name,String value);


01_会话技术的概述
会话技术
会话可以简单理解为,一个用户打开一个浏览器,在同一个WEB应用上,点击多个超链接,访问多个WEB资源,
然后关闭浏览器,那这整个过程我们称之为一个会话
作用
会话技术可以保存用户在会话过程中所产生的数据
会话技术也可以让用户在同一个会话中实现数据的共享

想保存数据到购物车 不重要  个人私有
保存哪里 服务器? 数据库 淘宝 京东 不登录 
编程最重要的域对象  域对象 临时存储数据
浏览器
可能会被清掉 服务器怎么知道浏览器里面有购物车数据 --每次访问服务器的时候把这个数据给带过去
服务器
占用空间 弄混 我怎么识别这个数据是谁的 我怎么让用户证明这个数据是他的
存在浏览器,主要问题是带来带去  存服务器主要问题是 我要识别这个数据是谁的

归根到底: 会话技术就是用来临时保存数据的


02_会话技术的分类
cookie
cookie是一种客户端技术,程序可以把每一个用户特有的数据,以响应头set-cookie发送给每一个用户的浏览器,那最终会以文件的形式保存在用户的硬盘上,
当用户再次使用浏览器来访问我们的WEB服务器,用户的浏览器会带上他特有的数据,而我们的程序所处理的则是来访用户特有的数据。
session
session是一种服务器技术,WEB服务器会在运行时为每一个用户的每一个会话创建一个其独享的HttpSession对象,
由于session对象是用户独享的,所以我们可以使用session对象来保存用户在一个会话过程中所产生的数据。
session对象也是一个域对象,范围是整个会话

注意:
cookie 把数据保存在用户的硬盘上
session 把数据保存在服务器的内存上

会话: 打开淘宝--浏览--关闭 一个会话
cookie
存在浏览器
1,服务器先创建出来
2,随着响应带到浏览器,然后浏览器做临时保存,保存完之后,下次请求在带回去
优点:减少服务器的压力,服务器内存可以少用一点
缺点:
1,换一个浏览器就获取不到
2,随时都会被清理,适合保存不重要的东西
3,带来带去,占用带宽,适合存小的东西,如果过大,用户等待的时候很长
4,数据传来传去, 不安全 
总结: 不必要的,比较小的,不涉及安全性的内容,用cookie

session
存在服务器

session 就是一个域对象,(setAttribute getAttribute,removeAttribute),就是通过这个保存数据

03_记录用户上次访问时间分析  访问网站统计量
	第一次访问
		服务器端
			判断是否有cookie信息,给出欢迎提示,记录本次访问时间
			发送响应头
			
	再次访问
		服务器端
			判断是否有cookie信息,显示上次访问时间,记录本次访问时间
			发送响应头
			
	对于cookie 需要关注
	1,在服务器端怎么创建一个cookie//Cookie c = new Cookie("lastAccessTime",now);
	2,如何把cookie响应到客户端  //response.addCookie(c);
	3,在浏览器发送回来的时候,我们服务器端怎么获得这个cookie//Cookie[] cs = request.getCookies();
	
	
04_记录用户上次访问时间
	1,拿到指定的cookie信息
	2,判断是否为null
		如果为null,给出提示信息
		否则,获取上次的访问时间,并显示
	3,获得当前的时间存在cookie当中,发到客户端

	步骤;
		//记录用户上次的访问时间
		response.setContentType("text/html;charset=UTF-8");
		PrintWriter out = response.getWriter();
		
		//获取cookie信息
		Cookie[] cs = request.getCookies();
		Cookie cookie = null;
		
		if(cs != null) {
			for (int i = 0; i < cs.length; i++) {
				String name = cs[i].getName();
				if("lastAccessTime".equals(name)) {
					cookie = cs[i];
					break;
				}
			}
		}
		
		//判断是否有上次的访问时间
		if(cookie == null) {
			//如果没有上次的访问时间,需要给出提示信息
			out.println("欢迎第一次访问");
		}
		else {
			//如果有上次的访问时间,需要获取上次的访问时间并显示
			String value = cookie.getValue();
			out.println("您上次的访问时间为:" + value);
		}

		//获取这次的访问时间(当前的系统时间)
		SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd hh:mm:ss");
		String now = sdf.format(new Date());
		
		//创建Cookie对象
		Cookie c = new Cookie("lastAccessTime",now);
		//记录用户这次的访问时间,并发送至客户端
		response.addCookie(c);
		
05_封装获取Cookie对象的功能
	/*
	 * 根据指定的cookie名称返回其对应的cookie对象
	 * 		参数:
	 * 			1.Cookie[]
	 * 			2.cookie的名称
	 * 		返回值:
	 * 			1.如果查找到了想要的cookie对象,返回这个cookie对象
	 * 			2.如果没有查找到想要的cookie对象,返回null
	 * 
	 */
	
	public static Cookie getCookie(Cookie[] cs,String name) {
		if(cs != null) {
			for (int i = 0; i < cs.length; i++) {
				String cookieName = cs[i].getName();
				if(cookieName.equals(name)) {
					//说明找到了想要的cookie对象
					return cs[i];
				}
			}			
		}		
		return null;
	}
07_Cookie的常用方法

		构造方法
			Cookie(String name,String value);
		获取名称
			String getName();
		获取值
			String getValue();
		设置有效时间(过期时间)
			void setMaxAge(int expiry) 
		设置路径
			void setPath(String uri)//
			当用户访问这个路径下的web资源,或者是这个路径下子路径的资源,他都会自动携带这个cookie
	
	设置有效时间	
		cookie.setMaxAge(60 * 60 * 24);//有效期一天
		cookie.setMaxAge(-1);//当浏览器关闭,会话结束后cookie会自动的被删除
		cookie.setMaxAge(0);//cookie会立刻被删除
		cookie.setMaxAge(Integer.MAX_VALUE);//最长的有效时间
		
	设置路径
		cookie.setPath("/myCookie");//cookie的默认路径是当前WEB应用的根路径
		cookie.setPath(request.getContextPath());//推荐使用这个方法,比较灵活
08_记住用户名
	经典的Cookie应用场景
	
	LoginUIServlet 登录UI界面,只负责展示页面
	LoginServlet 提交之后的跳转页面,负责处理逻辑判断
	IndexServlet 登录成功之后的跳转页面
	
09_记住用户名2	
	LoginServlet 提交之后的跳转页面,负责处理逻辑判断
		登录成功之后,根据记住用户名复选框的状态来设置Cookie
		if ("1".equals(remember)) {
			//需要记住用户名
			//创建Cookie对象
			Cookie cookie = new Cookie("username", username);
			//设置cookie的有效时间
			cookie.setMaxAge(Integer.MAX_VALUE);
			//发送cookie至客户端
			response.addCookie(cookie);
		}else {
			//不需要记住用户名
			Cookie cookie = new Cookie("username", "");
			cookie.setMaxAge(0);
			response.addCookie(cookie);
		}
			
	LoginUIServlet 登录UI界面,只负责展示页面
	
		获取cookie
			Cookie[] cs = request.getCookies();
			Cookie cookie = CookieUtils.getCookie(cs, "username");
			String username = "";
			String checked = "";
			
			if (cookie != null) {
				username = cookie.getValue();
				checked = "checked = 'checked'";
			}
		填充数据
			out.println("用户名:<input type='text' name='username' value='"+username+"' />");
			out.println("<input type='checkbox' name='remember' value='1'"+checked+" />记住用户名");


10_session的概述

	域对象
	 需要掌握
		1,怎么获取session对象
		2,什么时候用session对象
		3,怎么存数据 取数据 销毁
	
		WEB服务器可以为每一个来访的用户浏览器创建一个会话对象(session对象),
		如果需要保存用户的数据,我们的程序可以把用户的数据保存在用户浏览器独享的session对象中,
		如果用户再次的使用浏览器来访问其他的WEB资源,其他的WEB资源也可以通过session对象来获取这个用户的数据,以便为这个用户再次的服务
		session对象由WEB服务器创建,我们可以通过请求对象的方法getSession()来获取。
		
	cookie和session的区别
		cookie
			是一种客户端技术,有大小和数量的限制,把数据保存在客户端,所以相对的不安全
		session
			是一种服务器端技术,没有大小和数量的限制,把数据保存在服务器端,所以相对的安全

	如何区分一个session是哪个用户的,这个才是最难
	银行 开保险柜 给你钥匙
	关键点: 这个钥匙,怎么给到客户  如何让客户每次来的时候都带上钥匙  用的cookie
	所以某种意义上 session依赖于cookie  id id存在cookie
			
11_session的实现原理
	基于cookie
	
	第一次调用 getSession方法 发现客户端没有session对象,就会创建一个新的session对象
	并且把session对象id以Cookie的形式发给客户端
	客户端再次访问服务器端(severlet),发现他带了一个sessionid,就会查找对应的session对象
	
	如何获得session对象 直接调用 request.getSession() 一定返回一个session对象,我们就可以直接使用
	
	getSession()细节
		第一次来,没有携带jsessionid ,就创建一个新的session
		第二次来,携带jsessionid ,根据这个jsessionid去查找对应的session,如果找到就直接返回
				 携带jsessionid,根据这个jsessionid找不到对应的session,重新创建一个session并返回
	 
	
12_使用session对象实现数据的共享
	
	//获取session对象,如果客户端没有对应的session对象,则创建新的session对象并返回
	HttpSession session = request.getSession();
	
	//设置数据
	session.setAttribute("username", "wangwu");
	
	//获取数据
	session.getAttribute("username");
	
	//删除数据
	session.removeAttribute("username");
	
	cookie --- 传输 --转码    session 存在服务器 不需要
	
	一次会话的时候, 只需要登录一次,保证所有的页面都知道你登录
	给一个标记
	这个标记保存到哪里好
	1,要求
		实效性 
		安全
		整个会话的页面都可以使用 
	
	存在session中 
	cookie 窃取
	request 一次请求就没有
	ServletContext每个人都有登录状态

	
	
13_使用session实现用户登陆(初始化数据)
	用户类 User
	模拟数据库 UserDB

14_使用session实现用户登陆(页面实现)
	LoginUIServlet  登录界面
	IndexUIServlet	首页
		
15_使用session实现用户登陆(核心功能实现)
	用户登录功能(LoginServlet)
	共享用户登录状态的功能
	
	//用户名和密码正确,登陆成功后将用户名添加到session对象中
	HttpSession session = request.getSession();
	session.setAttribute("username", username);
	
	//获取session对象
	HttpSession session = request.getSession();
	//获取用户的登陆状态
	Object username = session.getAttribute("username");
	

16_使用session实现用户登陆(注销功能实现) 
	LogoutServlet 登出界面       
	
	//获取session对象
	HttpSession session = request.getSession();
	
	//删除数据,删除用户在session中的数据---不推荐
	session.removeAttribute("username");

	//销毁session对象
	session.invalidate();
	

17_session对象的生命周期
	一个对象从创建到销毁的整个过程
	时间:
		创建: 第一次调用getSession()创建Cookie对象
		销毁: 1,超时 默认30分钟(从最后一次请求算起)  
			  2,手动调用invalidate()方法
			  3,非正常关闭服务器
	
	
	钝化
		当我们使用正确的方式关闭tomcat,tomcat会把session对象以及session对象所存储的数据持久化到tomcat的work目录下,
		以便tomcat再次启动的时候可以恢复这些数据 

18_钝化的注意事项
	钝化就是持久化 必须要实现序列化接口

cookie案例:

步骤分析:
【步骤一】:准备登陆的案例.
【步骤二】:在统计人数的Servlet中.判断是否是第一次访问.
【步骤三】:根据是否是第一次显示不同的信息,同时将当前的时候保存到Cookie中.
代码实现
public class CountServlet extends HttpServlet {
	private static final long serialVersionUID = 1L;

	protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		response.setContentType("text/html;charset=UTF-8");
		Integer count = (Integer) this.getServletContext().getAttribute("count");
//		response.getWriter().println("<h1>现在网站被访问的次数为:"+count+"</h1>");
		
		/**
		 * 获得浏览器中带过来的所有的Cookie信息,从数组中查找有没有指定名称的Cookie
		 * 判断用户是否是第一次访问:(从数组中没有找到指定名称的Cookie)
		 * * 如果是第一次:显示欢迎,记录当前访问的时间存入到Cookie中.
		 * * 如果不是第一次:显示欢迎,上一次访问时间,同时记录当前访问的时间存入到Cookie中。
		 */
		// 获得浏览器带过来的所有的Cookie:
		Cookie[] cookies = request.getCookies();
		// 从数组中查找指定名称的Cookie:
		Cookie cookie = CookieUtils.findCookie(cookies, "lastVisit");
		// 判断是否是第一次:
		if(cookie == null){
			// 第一次访问
			response.getWriter().println("您是第"+count+"位访客!");
		}else{
			// 不是第一次
			Long l = Long.parseLong(cookie.getValue());
			Date d = new Date(l);
			response.getWriter().println("您是第"+count+"位访客! 上次访问时间是:"+d.toLocaleString());
		}
		// 创建一个Cookie对象:
		Cookie c = new Cookie("lastVisit",""+System.currentTimeMillis());
		// 保存到浏览器端:
		response.addCookie(c);
	}

	protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		doGet(request, response);
	}

}

案例二:记录用户的商品浏览记录

需求:
在购物网站上浏览商品的信息,商家为了留住用户,记住之前浏览的一些商品.
1.3.2.2步骤分析:
【步骤一】:在登录完成后,显示商品列表页面.
【步骤二】:为商品列表页面做一些准备工作.
【步骤三】:点击某个商品,将商品ID传递一个Servlet.
【步骤四】:在Servlet中:判断是否是第一次浏览商品
【步骤五】:如果是第一次:将商品的ID存入到Cookie中即可.
【步骤六】:如果不是第一次:判断该商品是否已经浏览了.
【步骤七】:如果浏览器过.删除之前元素,将该元素添加到最前面.
【步骤八】:如果没有浏览过该商品.判断最大长度,没有超过限制,直接加到最前,如果已经超过限制,删除最后一个,将其插入到最前.
代码实现:
public class ProductServlet extends HttpServlet {
	private static final long serialVersionUID = 1L;

	protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		/**
		 * * 接收商品id.
		 * * 接收从客户端带过来的所有Cookie.
		 * * 从Cookie的数组中查找指定名称的Cookie.
		 * * 判断是否是第一次浏览商品:
		 *     * 第一次浏览商品
		 *        * 直接将商品的ID存入到Cookie.
		 *        * 将Cookie回写到浏览器.
		 *     * 不是第一次浏览商品 1-2
		 *        * 判断当前的商品是否已经在浏览记录.
		 *            * 已经存在: 2-1 移除当前元素,将当前元素添加到最开始.
		 *            * 没在浏览记录中: 
		 *                * 判断是否已经超过了最大长度:如果超过 2-1-3:删除最后一个 将当前元素添加到最前面.
		 *                * 没有超过:直接将该元素添加到最前位置.
		 *        * 将转换的id的值存入到Cookie,回写浏览器.
		 */
		// 接收id:
		String id = request.getParameter("id");
		// 获得所有的Cookie的信息:
		Cookie[] cookies = request.getCookies();
		// 判断是否是第一次:
		Cookie cookie = CookieUtils.findCookie(cookies, "history");
		if(cookie == null){
			// 第一次浏览商品
			Cookie c = new Cookie("history",id);
			c.setPath("/day11");
			c.setMaxAge(60*60*24*7);
			response.addCookie(c);
		}else{
			// 不是第一次浏览
			// 判断选择的商品是否已经在浏览记录中 2-1
			String value = cookie.getValue();
			String[] ids = value.split("-");
			// 将数组变为集合:
			LinkedList<String> list = new LinkedList<String>(Arrays.asList(ids));
			if(list.contains(id)){
				// 之前浏览过该商品
				list.remove(id); // 1-2-3
				list.addFirst(id);
			}else{
				// 没有浏览过该商品.
				if(list.size() >=3 ){
					// 超过3个
					list.removeLast();
					list.addFirst(id);
				}else{
					// 没到3个.
					list.addFirst(id);
				}
			}
			// 将list中的元素取出,使用-连接上保存到Cookie,写回浏览器.
			StringBuffer sb = new StringBuffer();
			for(String s:list){
				sb.append(s).append("-");
			}
			String sValue = sb.toString().substring(0,sb.length()-1);
			System.out.println(sValue);
			// 存入到Cookie中
			Cookie c = new Cookie("history",sValue);
			c.setPath("/day11");
			c.setMaxAge(60*60*24*7);
			response.addCookie(c);
		}
		
		request.getRequestDispatcher("/demo2/product_info.htm").forward(request, response);
	}

	protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		doGet(request, response);
	}

}
清空浏览记录:

删除持久性的Cookie:
public class ClearServlet extends HttpServlet {
	private static final long serialVersionUID = 1L;

	protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		Cookie cookie = new Cookie("history",null);
		cookie.setPath("/day11");
		cookie.setMaxAge(0);
		response.addCookie(cookie);
		
		response.sendRedirect("/day11/demo2/product_list.jsp");
	}

	/**
	 * @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse response)
	 */
	protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		// TODO Auto-generated method stub
		doGet(request, response);
	}

}


Session案例:

将商品添加到购物车:

需求:
查看某个商品详情的时候,添加到购物车.需要将商品添加到购物车.

【步骤一】:点击加入购物车提交到Servlet
【步骤二】:在Servlet将购物的商品存入到Session中.
【步骤三】:可以创建一个Map集合用于保存购物信息Map的key可以是商品的名称,Map的value是数量.
【步骤四】:在购物车页面中显示Map中的数据就可以.
public class CartServlet extends HttpServlet {
	private static final long serialVersionUID = 1L;

	protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		// 接收商品名称:
		String name = new String(request.getParameter("name").getBytes("ISO-8859-1"),"UTF-8");
		// 创建Map集合用于保存购物信息.Map<String,Integer> Map的key是商品的名称 value是购买的数量.
		Map<String,Integer> map = (Map<String, Integer>) request.getSession().getAttribute("cart");
		if(map == null){
			map = new LinkedHashMap<String,Integer>();
		}
		// 判断购物车中是否已经买了该商品.
		if(map.containsKey(name)){
			// map中已经有该商品:// * 如果购物车中已经有该商品: 获得到Map中该商品的数量+1。 存回到Map集合中.
			Integer count = map.get(name);
			count++;
			map.put(name, count);
		}else{
			// map中没有该商品.// * 如果购物车中没有改商品: 将商品添加到Map集合中 数量1.
			map.put(name, 1);
		}
		
		
		// * 将Map集合保存到session中.
		request.getSession().setAttribute("cart", map);
		response.setContentType("text/html;charset=UTF-8");
		response.getWriter().println("<h3><a href='/day11/demo2/product_list.jsp'>继续购物</a> | <a href='/day11/demo2/cart.jsp'>去结算</a></h3>");
	}
Session是域对象:
session何时创建和销毁?作用范围:
* 创建:服务器端第一次调用getSession()创建session.
* 销毁:三种情况销毁session:
    * 1.session过期. 默认过期时间为30分钟.
    * 2.非正常关闭服务器.如果正常关闭session序列化到硬盘.
    * 3.手动调用session.invalidate();
* 作用范围:多次请求.(一次会话)

案例:进行一次性验证码的校验

1.5.1需求:
在登录的页面中,需要有一个验证码的校验.

【步骤一】:生成验证码,将生成验证码的随机的4个字母或数字保存到session中.
【步骤二】:在页面中输入验证码值,点提交.
【步骤三】:在Servlet中从表单中获得验证码从session中获得一个验证码.
【步骤四】:比对两个验证码值是否一致.
【步骤五】:将session中保存的验证码清空.
代码实现:
	protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		// 校验验证码程序:
		String code1 = request.getParameter("code");
		String code2 = (String) request.getSession().getAttribute("code");
		request.getSession().removeAttribute("code");
		if(!code1.equalsIgnoreCase(code2)){
			request.setAttribute("msg", "验证码输入错误!");
			request.getRequestDispatcher("/demo2/login.jsp").forward(request, response);
			return ;
		}
   ...
}
使用JS控制图片切换:
 <script type="text/javascript">
 	function changeImg(){
 		document.getElementById("img1").src="/day11/CheckImgServlet?time="+new Date().getTime();
 	}
 </script>












  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值