一. 浏览器和服务器之间通信的简单介绍引出Cookie和Session(只是简单的简介,不包含协议方面的知识)
1.当我们在浏览器中输入一个地址后,回车后就可以看到浏览器给我们展示的漂亮页面。在这个过程中浏览器和服务器都做了什么呢?下面的解释只是浏览器与服务器之间
通信的最简单的形式,也称之为一次会话。
① 首先我们在地址栏上输入我们想要打开的网址,按下回车。这样一个请求就由浏览器发往服务器。
② 服务器的网络设备接收到数据后,在传向服务器软件。
③ 服务软件得到请求后,进行一系列逻辑处理,然后生成响应并发向浏览器。
④ 响应通过服务器的网络设备,通过网线传向客户端的网络设备。
⑤ 客户端的网络设备将响应解析,然后传给浏览器软件,浏览器在将响应解析,这样我们就在浏览器上看到了想要看到的网页。
2. web语言HTTP 是无状态的,所以在服务器处理完客户的请求,并收到客户的应答后,立即就断开与客户端的连接。但是,我们访问一个网站的时候并不是只做一件事,而是
要做好多事情,然而这种无状态的连接让服务器无法识别后续我们发出的请求和前一个请求是同一个人出发的,或者说当有很多人在访问同一个网站时,无法识别谁是谁。因此就出
现了Cookie和Session这两个技术。这两个技术就是保持客户端和服务器会话过程的两个技术。
Cookies具体是如何实现的呢?当你在浏览网站的时候,Web服务器会先发送一些数据放在你的计算机上,这个数据就叫Cookie。Cookie 会把你在网站上所打的文字或是
一些选择都记录下来。当下次你再访问同一个网站,Web服务器会先看看有没有它上次留下的Cookies资料,有的话,就会依据Cookie里的内容来判断使用者,送出特定的网页内
容给你。因此Cookies是一种客户端技术,它存放在客户端。
Session是另一种记录客户状态的机制。服务器在运行时可以为每一个用户的浏览器创建一个其独享的session对象,由于session为用户浏览器独享,所以用户在访问服
务器的web资源时,可以把各自的数据放在各自的session中,当用户再去访问服务器中的其它web资源时,其它web资源再从用户各自的session中取出数据为用户服务。
Session是一种服务器端技术,它存放在服务器端。
二.Cookie简介
Cookie是网站为了辨别用户身份、进行session跟踪而以键值对(key/value)的形式储存在用户本地终端上的数据。
Cookie是由服务器端生成,发送给浏览器,浏览器会将Cookie的key/value保存到某个目录下的文本文件内,下次请求同一网站时就发送该Cookie给服务器(前提是浏览器设
置为启用cookie)。这样服务器可以知道该用户是否是合法用户以及是否需要重新登录等,服务器可以设置或读取Cookies中包含信息,借此维护用户跟服务器会话中的状态。
三. Java里的Cookie 就是Servlet API 里提供的 javax.servlet.http.Cookie
1. Cookies的具体信息为:public class Cookie extends java.lang.Objectimplements java.lang.Cloneable
2. 主要的方法
① public Cookie(java.lang.String name,java.lang.String value)
构造函数,实例化一个Cookie,传入键(name)和值(value)。
② public java.lang.String getName()
获取Cookie的名字。
③ public java.lang.String getValue()
获取Cookie的值。
public void setValue(java.lang.String newValue)
设置Cookie的值
④ public void setMaxAge(int expiry)
设置Cookie的最大保存时间,即cookie的有效期,当服务器给浏览器回送一个cookie时,如果在服务器端没有调用setMaxAge方法设置cookie的有效期,
那么cookie的有效期只在一次会话过程中有效,用户打开浏览器,访问某一网站,访问服务器多个web资源,然后关闭浏览器,整个过程称之为一次会话。
当用户关闭浏览器,会话就结束了,此时cookie就会失效。
public int getMaxAge()
获取Cookies的有效期
⑥ public void setPath(java.lang.String uri)
设置cookie的有效路径,比如把cookie的有效路径设置为"/abc",那么浏览器访问"abc"目录下的web资源时,都会带上cookie。
如果把cookie的有效路径设置为"/abc/abcd",那么浏览器只有在访问"abc"目录下的"abcd"这个目录里面的web资源时才会带上cookie一起访问。
public java.lang.String getPath()
得到cookie的有效路径
⑦ public void setDomain(java.lang.String pattern)
设置cookie的有效域
public java.lang.String getDomain()
得到cookie的有效域
3. public interface HttpServletRequest extends ServletRequest 这个接口中有操作Cookie的方法
public Cookie[] getCookies()
获取Cookie实例
4. public interface HttpServletResponse extends ServletResponse 这个接口同样有操作Cookie的方法
public void addCookie(Cookie cookie)
给响应添加Cookie
四. Cookie小实例1____服务器端不设置Cookie过期时间
package com.hjj.servlet.three; import java.io.IOException; import java.io.PrintWriter; import java.text.DateFormat; import java.text.ParseException; import java.text.SimpleDateFormat; import java.util.Date; import javax.servlet.annotation.WebServlet; import javax.servlet.http.Cookie; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; @WebServlet(name="testCookies",urlPatterns="/testCookies") public class TestCookies extends HttpServlet{ protected void doGet(HttpServletRequest request,HttpServletResponse response) throws IOException{ response.setContentType("text/html"); response.setCharacterEncoding("UTF-8"); Cookie[] cookies = request.getCookies(); //第一次访问,结果为空 PrintWriter pw = response.getWriter(); if(cookies == null){ pw.println("您好,您是第一次访问该网站。"); pw.println("我们会将cookie对象添加到response对象中,这样服务器在输出response对象中的内容时就会把cookie也输出到客户端浏览器"); //如果是第一次访问该网站,则创建Cookie对象,并把它添加到响应中。这样返回给浏览器的响应中就会带有Cookie Cookie cookie = new Cookie("lastAccessTime",System.currentTimeMillis()+""); response.addCookie(cookie); }else{ pw.print("您好,您不是第一次访问该网站。上次访问网站的时间是:"); for(Cookie cookie: cookies){ //拿到cookie的名字 String name = cookie.getName(); if(name.equals("lastAccessTime")){ //拿到cookie的值 String value = cookie.getValue(); //把String类型的值转化为时间类型,在转化会String类型,即把 "1234567"这样的String转化为"2016-2-2 2:02:02"这样String类型 String time = new SimpleDateFormat("yyyy-MM-dd HH:mm").format(new Date(Long.parseLong(value))); pw.println(time); } } } } protected void doPost(HttpServletRequest request,HttpServletResponse response) throws IOException{ this.doGet(request, response); } }
1. 第一次在浏览器中输入 http://localhost:8080/one/testCookies
页面显示:
请求和响应为:
2. 再次刷新浏览器
页面显示:
您好,您不是第一次访问该网站。第一次访问网站的时间是:2016-04-30 17:16
请求和响应为:
3. 1和2两个实验在服务器端没有对cookie的过期时间做设置。因此当你做完前两个试验后,关闭浏览器,此时Cookie已经失效。再次打开浏览器,
然后重新请求 http://localhost:8080/one/testCookies 就和实验1的结果一样,再次刷新就和实验2的结果一样。
五. Cookie小实例1____服务器端手动设置Cookie过期时间
package com.hjj.servlet.three; import java.io.IOException; import java.io.PrintWriter; import java.text.SimpleDateFormat; import java.util.Date; import javax.servlet.annotation.WebServlet; import javax.servlet.http.Cookie; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; @WebServlet(urlPatterns="/testSetMaxAge") public class TestSetMaxAge extends HttpServlet{ protected void doGet(HttpServletRequest request,HttpServletResponse response) throws IOException{ response.setContentType("text/html"); response.setCharacterEncoding("UTF-8"); Cookie[] cookies = request.getCookies(); //第一次访问,结果为空 PrintWriter pw = response.getWriter(); if(cookies == null){ pw.println("第一次访问该网站"); Cookie cookie = new Cookie("lastAccessTime",System.currentTimeMillis()+""); int time = cookie.getMaxAge(); pw.println("默认的Cookie过期时间为:"+time); //设置Cookies过期时间为24小时,也就是一天 pw.println("在服务器端手动对Cookies过期时间进行设置"); cookie.setMaxAge(86400); pw.println("设置之后Cookie的过期时间为:"+cookie.getMaxAge()); response.addCookie(cookie); }else{ pw.print("不是第一次访问该网站。上次访问网站的时间是:"); for(Cookie cookie: cookies){ //拿到cookie的名字 String name = cookie.getName(); if(name.equals("lastAccessTime")){ String value = cookie.getValue(); String time = new SimpleDateFormat("yyyy-MM-dd HH:mm").format(new Date(Long.parseLong(value))); pw.println(time); } } } } protected void doPost(HttpServletRequest request,HttpServletResponse response) throws IOException{ this.doGet(request, response); } }
1. 第一次请求浏览器输入:http://localhost:8080/one/testSetMaxAge
页面显示:
请求和响应为:
响应头
2. 刷新页面
页面显示:
请求和响应为:
3. 关闭浏览器,然后再次打开浏览器重新请求,因为设置了Cookie的过期时间为24小时,因此再次访问之前的Cookie依然有效。
页面显示如下:
请求和响应为:
六. Cookies小结
- 一个Cookie是以键值对的形式存在的,设置一个Cookie必须包含name和value。
- 一个网站可以给一个浏览器发送多个Cookie,一个浏览器也可以存储多个网站提供的Cookie。
- 浏览器一般只允许存放300个Cookie,每个站点最多存放20个Cookie,每个Cookie的大小限制为4KB。
- 如果创建了一个cookie,并将他发送到浏览器,默认情况下它是一个会话级别的cookie(即存储在浏览器的内存中),用户退出浏览器之后即被删除。若希望浏览器将该cookie存储在磁盘上,则需要使用maxAge,并给出一个以秒为单位的时间。将最大时效设为0则是命令浏览器删除该cookie。
七. 删除Cooike
package com.hjj.servlet.three; import java.io.IOException; import java.io.PrintWriter; import java.text.SimpleDateFormat; import java.util.Date; import javax.servlet.annotation.WebServlet; import javax.servlet.http.Cookie; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; @WebServlet(urlPatterns="/testDeleteCookie") public class TestDeleteCookie extends HttpServlet { protected void doGet(HttpServletRequest request,HttpServletResponse response) throws IOException{ response.setContentType("text/html"); response.setCharacterEncoding("UTF-8"); Cookie[] cookies = request.getCookies(); //第一次访问,结果为空 PrintWriter pw = response.getWriter(); Cookie cookie = new Cookie("lastAccessTime",System.currentTimeMillis()+""); //删除cookie的方法 cookie.setMaxAge(0); response.addCookie(cookie); pw.print("我删除了cookie"); } protected void doPost(HttpServletRequest request,HttpServletResponse response) throws IOException{ this.doGet(request, response); } }
1. 浏览器请求:http://localhost:8080/one/testDeleteCookie
页面显示:
请求和响应为:
2. 之后每一次刷新页面,服务器返回的响应中都带有Set-Cookie。