Cookie&Session

案例:记录用户的上次访问的时间

需求:

当用户访问某些Web应用时,经常回显示出该用户上一次的访问时间,例如,QQ会显示上次的登录时间。

相关知识点

会话

一个客户但(浏览器)与Web服务器之间连续发生的一系列请求和响应过程,例如,一个用户在某网站上的整个购物过程就是一次会话。

HttpServletRequest和Httpresponse对象和ServletContext对象都可以对数据进行保存,但无法保存会话相关的数据!

 - HttpServlet存储的寿命只能是一次请求,而不是一系列的请求和响应,即将请求放到request作用域中,多次请求不能共享数据。
 - ServletContext对象保存数据时,同一个Web共享同一个ServletContext对象,因此无法区分不同的用户产生的会话。

cookie和session都是为了弥补http协议的无状态特性,对server端来说无法知道两次http请求是否来自同一个用户,利用cookie和session就可以让用户只登录一次,server就知道某个请求是否需用重新登录。

 - Cookie:用户第一次访问服务器,服务器会在响应消息中增加Set-Cookie头字段,将用户信息以Cookie的形式发送浏览器。浏览器将其保存在浏览器缓冲区,并且后续访问服务器都会将信息以Cookie的形式发送给Web服务器。使服务器分辨是哪个用户。cookie是保存在客户端的有大小和个数的限制,不安全。
 - Session:是用来存储或代表不同用户的不同信息的,而且Session一般也是存储在Cookie中,session是存在服务器,无大小和个数的限制,更加安全,session依赖于cookie。

在这里插入图片描述

Cookie

当用户通过浏览器访问Web服务器时,服务器会给客户端发送一些信息,这些信息会保存在Set-Cookie中,服务器会在response中返回Set-Cookie时,浏览器将其保存在Cookie中。这样,该浏览器再次访问服务器时,都会在请求头中将Cookie发送给服务器,方便服务器对浏览器做出正确的响应。

  • Cookie和浏览器有什么区别?
    • 浏览器可以缓存缓存任意内容,浏览器的缓存是为了避免同一页面需要多次请求而设计的,主要是为了提高用户体验和速度考虑的。
    • cookie只缓存服务器需要浏览器缓存的数据。因为HTTP协议是无状态的,服务器无法记录用户上一次的操作,这样就造成了交互上的阻碍。而服务器借由从Cookie中读取包含的信息,借以维护用户和服务器会话中的状态。
      Set-Cookie头字段中设置的Cookie遵循一定的语法格式:

Set-Cookie:user=itcast; Path=/;

Cookie必须以键值对的形式存在,user表示Cookie的名称,Path表示Cookie的属性,属性可以有多个,但属性之间必须用分号;和空格分隔。
在这里插入图片描述
Cookie在浏览器和服务器之间的传输过程

Cookie的基本使用

创建cookie:new Cookie(name,value)
将cookie发送给浏览器:HttpServletResponse.addCookie()
接收浏览器携带的所有cookie: HttpServletRequest.getCookies()

案例实现

流程分析

在这里插入图片描述

步骤分析
  1. 获得从客户端带过来的所有Cookie
  2. 从所有的Cookie中查找名称的Cookie
  3. 判断是否是第一次访问?是的话显示欢迎:否的话显示上次访问时间
  4. 记录当前的时间,并且利用Cookie将时间回写到浏览器端。
代码实现
public class LastAccessTimeServlet extends HttpServlet {

	public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		//获得当前时间
		Date date = new Date();
		SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd hh:mm:ss");
		String currentTime = format.format(date);
		
		//1.创建Cookie 记录当前的最新访问时间
		Cookie cookie = new Cookie("lastAccessTime",currentTime);
		cookie.setMaxAge(60*10*500);//设置保存cookie时间
		response.addCookie(cookie);
		
		//2.获得客户端携带cookie-----lastAccessTime
		String lastAccessTime =null;
		Cookie[] cookies = request.getCookies();
		if(cookies!=null){
			for(Cookie coo:cookies){
				if("lastAccessTime".equals(coo.getName())){
					lastAccessTime = coo.getValue();
				}
			}
		}
		
		response.setContentType("text/html;charset=UTF-8");
		if(lastAccessTime==null){
			response.getWriter().write("您是第一次访问");
		}else{
			response.getWriter().write("您上一次的访问时间是:"+lastAccessTime);
		}
	}

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

Cookie的总结

  • 会话级别的Cookie:默认的,关闭了浏览器Cookie就销毁了
  • 持久级别的Cookie:需要设置有效市场的,关闭浏览器也不会销毁Cookie
    • setMaxAge(int expiry);以秒为单位的时间,超过了该时间,超过了改时间后Cookie会自动销毁,setMaxAge(0);手动删除持久性的Cookie。
    • setPath(String uri);设置Cookie的有效途径
      • 1)cookie.setPath("/day16/demo");表示day16项目下demo子目录下所有的servlet,都可以访问当前cookie。但“/day16"或"/day16/aaa"将不能访问
      • 2)cookie.setPath("/day16"); 表示day16项目下的所有servlet都可以访问当前的cookie
      • 3)cookie.setPath("/");表示tomcat下的所有web项目均可以当问当前的cookie
  • cookie唯一表示:
    • 唯一标识:domain+path+name(类似java中 包+类名)

      • domain 域名,不同的网站使用的是不同的域名,cookie就不同。
      • path 路径,通过cookie.setPath()设置的内容
      • name cookie名称,通过new Cookie(name,…)确定的内容。
    • 例如如下表示的是两个cookie,可以同时存在

      • /web/a/b/CookieName
      • /web/a/CookieName
    • 如果路径和名称一样,两次addCookie()后者将覆盖前者。

Cookie的API

在这里插入图片描述

Session

HTTP的传输还有个问题,即明文传输。而且HTTP请求容易被篡改。又根据客户端信息不可靠原则,我们需要一个东西来验证用户的身份——Session。Session也可以做到Cookie的部分功能,但Session是保存在服务器上的。服务端的信息无法随便篡改,所以Session更加可靠。具体的做法一般是服务端和客户端之间不传输明文数据,而是传输一段经过特殊加密的密文,密文对应的服务器硬盘数据中才是真实的数据。这段数据根据不同的ID属性,在Session激活后从服务器磁盘中取出到内存中,再返回给浏览器。

Session的使用

相关api
//获取Session对象
request.getSession()//相当于boolean设置为true
request.getSession(boolean create)//true时,不存在session则创建,false不存在时返回null
//获取SessionId
getId()
//获取当前session对象的创建时间
getCreationTime()
//获取最后一次访问该session对象的时间
getLastAccessedTime()
//设置Session最大时效
setMaxInactiveInterval()
//获取Session最大时效
getMaxInactiveInterval()
//判断当前Session对象是不是新建的
/**
如果客户端请求消息中返回了一个与Servlet程序当前获得的HttpSession对象的会话标识号相同的会话标识号,则认为这个HttpSession对象不是新建的。
*/
isNew()
//销毁当前Session对象
invalidate()
//属性相关
setAttribute()
getAttribute()
removeAttribute()
getAttributeNames()
实例
public class SessionServlet1 extends HttpServlet {

	public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		/*
		 * request.getSession()方法内部会判断 该客户端是否在服务器端已经存在session
		 * 若存在,则直接返回该session
		 * 若不存在,创建一个session对象并返回
		 */
		//创建属于该客户端会话的私有的session区域
		HttpSession session = request.getSession();
		
		session.setAttribute("name", "gua");
		
		String id = session.getId();
		
		//手动创建一个存储JSESSIONID的Cookie 为该cookie设置持久化时间
		Cookie cookie = new Cookie("JSESSIONID",id);
		cookie.setPath("/WEB16/");
		cookie.setMaxAge(60*10);
		
		response.addCookie(cookie);
		response.getWriter().write("JSESSION:"+id);
	}

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

作用域总结

  • ServletContext:针对一个WEB应用。一个WEB应用只有一个ServletContext对象,使用该对象保存的数据在整个WEB应用中都有效
    • 创建:服务器启动的时候
    • 销毁:服务器关闭的时候或者项目移除
  • HttpSession:针对一次会话,使用该对象保存数据 ,一次会话(多次请求)内数据有效。
    • 创建:服务器第一次调用getSession()的时候,服务器创建session的对象
    • 销毁:
      • 1.非正常关闭服务器(正常关闭:session被序列化)
      • 2.Session过期了,默认时间是30分钟
      • 3.手动调用session的invalidate的方法
  • HttpServletRequest:针对一次请求。使用该对象保存数据,一次请求(即一个页面或转发的多个页面)内数据有效
    + 创建:客户端向服务器发送一次请求
    + 销毁:服务器为这次请求作出响应之后,销毁request
  • 三个作用域对象操作的API相同
    • 存放数据:setAttribute(name,value)
    • 获得数据:getAttribute(name)
    • 删除数据:removeAttribute(name)
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值