什么是Cookie
1)Cookie来自于Servlet规范中一个工具类,存在于Tomcat提供servlet-api.jar中
2)如果两个Servlet来自于同一个网站,并且为同一个浏览器/用户提供服务,此时借助于Cookie对象进行数据共享
3) Cookie存放当前用户的私人数据,在共享数据过程中提高服务质量
4) 在现实生活场景中,Cookie相当于用户在服务端得【会员卡】
5)利用Cookie实现会话管理是目前开发的主流方法,大多数动态页面都用了这一功能,并且其管理流程是自动完成的,不需要多大的开发工作量,
Cookie的工作原理
用户通过浏览器第一次向MyWeb网站发送请求申请OneServlet。
OneServlet在运行期间创建一个Cookie存储与当前用户相关数据
OneServlet工作完毕后,【将Cookie写入到响应头】交还给当前浏览器。
浏览器收到响应响应包之后,将cookie存储在浏览器的缓存一段时间之后,用户通过【同一个浏览器】再次【myWeb网站】发送请求申请TwoServlet时,
【浏览器需要无条件的将myWeb网站之前推送过来的Cookie,写入到请求头】发送过去。
此时TwoServlet在运行时,就可以通过读取请求头中cookie中信息,得到OneServlet提供的共享数据
Cookie的使用
服务端给客户端的数据,存储于客户端(浏览器)。由于是保存在客户端上的,所以存在安全问题,并且cookie是由个数和大小限制的(4KB),所以一般cookie用来存储一些比较小且安全性要求不高的数据,而且一般数据都会进行加密。
我们平时在登录某些网站时,关闭浏览器后再次打开登录,用户名密码等数据会自动填充在表单。
或者我们浏览淘宝的某个商品后,下次再打开发现出现的商品很多都是我们之前浏览的同类商品等。
这些都是cookie的应用场景。
同一个网站 OneServlet 与 TwoServlet 借助于Cookie实现数据共享。
OneServlet{
public void doGet(HttpServletRequest request,HttpServletResponse resp){
//1.创建一个cookie对象,保存共享数据(当前用户数据)
Cookie card = new Cookie("key1","abc");
Cookie card1= new Cookie("key2","efg");
****cookie相当于一个map
****一个cookie中只能存放一个键值对
****这个键值对的key与value只能是String
****键值对中key不能是中文
//2.【发卡】将cookie写入到响应头,交给浏览器
resp.addCookie(card);
resp.addCookie(card1)
}
}
TwoServlet{
public void doGet(HttpServletRequest request,HttpServletResponse resp){
//1.调用请求对象从请求头得到浏览器返回的Cookie
Cookie cookieArray[] = request.getCookies();
//2.循环遍历数据得到每一个cookie的key 与 value
for(Cookie card:cookieArray){
String key = card.getName(); 读取key "key1"
Strign value = card.getValue();读取value "abc"
}
}
}
常用方法:
Cookie cookie = new Cookie("account", account);//创建一个cookie,保存账号数据
cookie.setMaxAge(1*60*60*24);//cookie存在在本地的有效时长(单位为秒) 默认为-1 表示页面关闭cookie就失效
cookie.setDomain("");//设置在某个域名下生效
cookie.setPath("/login.jsp");//设置访问该域名下某个路径时生效
response.addCookie(cookie);//添加到response
Cookie[] cookies=request.getCookies();//获取cookies
cookie.getName();//cookie的name
cookie.getValue();//cookie的value
Cookie的销毁时机
- 在默认情况下,Cookie对象存放在浏览器的缓存中。因此只要浏览器关闭,Cookie对象就被销毁掉
- 在手动设置情况下,可以要求浏览器将接收的Cookie存放在客户端计算机上硬盘上,同时需要指定Cookie 在硬盘上存活时间。在存活时间范围内,关闭浏览器关闭客户端计算机,关闭服务器,都不会导致Cookie被销毁。在存活时间到达时,Cookie自动从硬盘上被删除
cookie.setMaxAge(60); //cookie在硬盘上存活1分钟
HttpSession是什么
1)HttpSession接口来自于Servlet规范下一个接口。存在于Tomcat中servlet-api.jar 其实现类由Http服务器提供。Tomcat提供实现类存在于servlet-api.jar
2)如果两个Servlet来自于同一个网站,并且为同一个浏览器/用户提供服务,此时借助于HttpSession对象进行数据共享
3)开发人员习惯于将HttpSession接口修饰对象称为【会话作用域对象】
4)Session是另一种记录客户状态的机制,不同的是Cookie保存在客户端浏览器中,而Session保存在服务器上。客户端浏览器访问服务器的时候,服务器把客户端信息以某种形式记录在服务器上。这就是Session。客户端浏览器再次访问时只需要从该Session中查找该客户的状态就可以了
HttpSession的实现
同一个网站(myWeb)下OneServlet将数据传递给TwoServlet
OneServlet{
public void doGet(HttpServletRequest request,HttpServletResponse response){
//1.调用请求对象向Tomcat索要当前用户在服务端的私人储物柜
HttpSession session = request.getSession();
//2.将数据添加到用户私人储物柜
session.setAttribute("key1",共享数据)
}
}
当服务器访问twoservlet时
TwoServlet{
public void doGet(HttpServletRequest request,HttpServletResponse response){
//1.调用请求对象向Tomcat索要当前用户在服务端的私人储物柜
HttpSession session = request.getSession();
//2.从会话作用域对象得到OneServlet提供的共享数据
Object 共享数据 = session.getAttribute("key1");
}
}
常用方法:
HttpSession session = request.getSession();//获取session,没有则创建
session.getId();//获取sessionId
session.getAttribute("key");//获取存储的某个值
session.setAttribute("key","value");//存储数据,value是object类型
session.getCreationTime();//获取session创建的时间
session.removeAttribute("key");//移除某个数据
session.invalidate();//重置session,使session失效
session.setMaxInactiveInterval(1*60*60);//设置会话的超时时间(单位:秒),默认30分钟
session.getLastAccessedTime();//最后一次修改session的时间
注意:getSession() 与 getSession(false)
1)getSession(): 如果当前用户在服务端已经拥有了自己的私人储物柜.要求tomcat将这个私人储物柜进行返回
如果当前用户在服务端尚未拥有自己的私人储物柜 要求tocmat为当前用户创建一个全新的私人储物柜
2)getSession(false):如果当前用户在服务端已经拥有了自己的私人储物柜. 要求tomcat将这个私人储物柜进行返回
如果当前用户在服务端尚未拥有自己的私人储物柜 此时Tomcat将返回null
HttpSession’销毁时机
1.用户与HttpSession关联时使用的Cookie只能存放在浏览器缓存中。
2.在浏览器关闭时,意味着用户与他的HttpSession关系被切断。
3.由于Tomcat无法检测浏览器何时关闭,因此在浏览器关闭时并不会。导致Tomcat将浏览器关联的HttpSession进行销毁。
4.为了解决这个问题,Tomcat为每一个HttpSession对象设置【空闲时间】, 这个空闲时间默认30分钟,如果当前HttpSession对象空闲时间达到30分钟,此时Tomcat认为用户已经放弃了自己的HttpSession,此时Tomcat就会销毁 掉这个HttpSession。
HttpSession 与 Cookie 区别:
【面试题】很重要
- 存储位置: 一个在天上,一个在地下 Cookie:存放在客户端计算机(浏览器内存/硬盘)
HttpSession:存放在服务端计算机内存 - 数据类型:
Cookie对象存储共享数据类型只能是String
HttpSession对象可以存储任意类型的共享数据Object - 数据数量:
一个Cookie对象只能存储一个共享数据
HttpSession使用map集合存储共享数据,所以可以
存储任意数量共享数据 - 参照物:
Cookie相当于客户在服务端【会员卡】HttpSession相当于客户在服务端【私人保险柜】
URL地址重写
URL地址重写是对客户端不支持Cookie的解决方案。URL地址重写的原理是将该用户Session的id信息重写 到URL地址中。服务器能够解析重写后的URL获取Session的id。这样即使客户端不支持Cookie,也可以使用Session来记录用户状态。 HttpServletResponse类提供了encodeURL(Stringurl)实现URL地址重写,例如:
<a href="<%=response.encodeURL("index.jsp?c=1&wd=Java") %>">
Homepage</a>
该方法会自动判断客户端是否支持Cookie。如果客户端支持Cookie,会将URL原封不动地输出来。如果客户端不支持Cookie,则会将用户Session的id重写到URL中。重写后的输出可能是这样的:
<ahref="index.jsp;jsessionid=0CCD096E7F8D97B0BE608AFDC3E1931E?c=
1&wd=Java">Homepage</a>
即在文件名的后面,在URL参数的前面添加了字符串“;jsessionid=XXX”。其中XXX为Session的 id。分析一下可以知道,增添的jsessionid字符串既不会影响请求的文件名,也不会影响提交的地址栏参数。用户单击这个链接的时候会把 Session的id通过URL提交到服务器上,服务器通过解析URL地址获得Session的id。
如果是页面重定向(Redirection),URL地址重写可以这样写:
if(“administrator”.equals(userName))
{
response.sendRedirect(response.encodeRedirectURL(“administrator.jsp”));
return;
}
效果跟response.encodeURL(String url)是一样的:如果客户端支持Cookie,生成原URL地址,如果不支持Cookie,传回重写后的带有jsessionid字符串的地址。
禁用Cookie
打开项目sessionWeb的WebRoot目录下的META-INF文件夹(跟WEB-INF文件夹同级,如果没有则创建),打开context.xml(如果没有则创建),编辑内容如下:
代码1.11 /META-INF/context.xml
<?xml version='1.0' encoding='UTF-8'?><Context path="/sessionWeb"cookies=“false”>
或者修改Tomcat全局的conf/context.xml,修改内容如下:
代码1.12 context.xml
<!-- ... 中间代码略 -->
部署后TOMCAT便不会自动生成名JSESSIONID的Cookie,Session也不会以Cookie为识别标志,而仅仅以重写后的URL地址为识别标志了。
注意:该配置只是禁止Session使用Cookie作为识别标志,并不能阻止其他的Cookie读写。也就是说服务器不会自动维护名为JSESSIONID的Cookie了,但是程序中仍然可以读写其他的Cookie。