开始之前,先介绍下会话技术的概念
当用户打开浏览器的时候,访问不同的资源(发送不同的请求),直到用户将浏览器关闭,可以认为这是一次会话.
作用:
因为http协议是一个无状态的协议,它记录不论上次访问的内容.用户在访问过程中难免会产生一些数据,
通过会话技术就可以将起保存起来.
例如:
用户登录
验证码
购物车
访问记录
.....
小饼干 小甜点
(面试官三个屋子的场景)
/******大学生面试进入三个不同的房间,只有在第一个面试官给额头上的密码才可以进入下一轮
大学生就相当于浏览器,而面试官就相当于服务器,额头上的密码就相当于cookie****/
cookie是由服务器生成,通过response将cookie写回浏览器(set-cookie),保留在浏览器上,
下一次访问,浏览器根据一定的规则携带不同的cookie(通过request的头 cookie),我们服务器就可以接受cookie
创建cookie,键值对的形式
可参见下图:
1.cookie的api:
new Cookie(String key,String value)
2. 写回浏览器:
response.addCookie(Cookie c)
3. 获取cookie:
Cookie[] request.getCookies()
4.cookie的常用方法:
getName():获取cookie的key(名称)
getValue:获取指定cookie的值5.设置cookie在浏览器端存活时间 以秒为单位
setMaxAge(int 秒)6.删除cookie
setMaxAge(0);7.当我们访问的路径中包含此cookie的path,则携带
默认路径: setPath(String path):
注意:
访问serlvet的路径,从"/项目名称"开始,到最后一个"/"结束
例如:
访问的serlvet路径:
/day06/a/b/hello
默认路径为:
/day06/a/b(这样才会携带cookie,也就是关掉浏览器重新进去之访问相同的路径内容相同的)/day06/a都不行
服务器接收到用户的HTTP请求报文之后,从报文头获取到该用户的Cookie,从里面找到所需要的东西。
code是和cookie用到的code
code是重要的code
package com.javaweb.RemServlet;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.Date;import javax.servlet.ServletException;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
/**
* 记录上次访问时间
*/
public class RemServlet extends HttpServlet {protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
//0.设置编码(因为是向浏览器写东西)
response.setContentType("text/html;charset=utf-8");
PrintWriter w = response.getWriter();
//1.获取指定名称的cookie自己构造(里面的参数为key-value)
Cookie c=getCookieByName("lastTime",request.getCookies());
//2.判断cookie是否为空
if(c == null){
//cookie为空 提示 第一次访问
w.print("您是第一次访问!");
}else{
//cookie不为空 获取value 展示 上一次访问的时间
String value = c.getValue();// lastTime=12312324234的形式,要转为long
long time = Long.parseLong(value);
Date date = new Date(time);
w.print("您上次访问时间:"+date.toLocaleString());
}
//3.将当前访问时间记录
//3.1创建cookie
c=new Cookie("lastTime",new Date().getTime()+"");
//持久化cookie一个小时
c.setMaxAge(3600);
//设置路径
c.setPath(request.getContextPath()+"/");
//3.2写回浏览器
response.addCookie(c);
}/**
* 通过名称在cookie数组获取指定的cookie
* @param name cookies名称
* @param cookies Cookie数组
* @return
* 私有构造注意*/
private Cookie getCookieByName(String name, Cookie[] cookies) {
if(cookies!=null){
for (Cookie c : cookies) { //foreach遍历
//通过名称获取
if(name.equals(c.getName())){
//返回
return c;
}
}
}
return null;
}protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
doGet(request, response);
}}
6.1需求:
当用户访问一个商品的时候,需要将该商品保留在浏览记录中
6.2步骤分析:
6.2.1
因为运行的是java代码,jsp可以,html不行,所以要先转换
1.先将product_list.htm转成jsp
2.点击一个商品,展示该商品的信息,将该商品id记录到cookie (GetProductById)
但是访问之前的商品信息也得记录
在servlet中该如何做?
6.2.2
首先是设置编码
获取之前的浏览记录 例如名称:ids
判断cookie是否为空
若为空 将当前商品的id起个名称 ids 放入cookie中 ids=1
若不为空,获取值 例如:ids=2-1 当前访问的id=1 使用"-"分割商品id
判断之前记录中有无该商品
若有:
将当前的id放入前面 结果 ids=1-2
若没有:
继续判断长度是否>=3
若>=3,移除最后一个,将当前的id放入最前面
若<3,直接将当前的id放入最前面.
若 ids=3-2-1 现在访问1 结果 ids=1-3-2
若 ids=4-3-2 现在访问1 结果 ids=1-4-3
6.2.3
3.再次回到product_list.jsp页面,需要将之前访问商品展示在浏览记录中
获取ids 例如:ids=2-3-1(的形式)
切割
代码如下:
Utils的代码(通过制定名称来获取cookie)
package com.javaweb.utils;
import javax.servlet.http.Cookie;
public class CookUtils {
public static Cookie getCookieByName(String name, Cookie[] cookies) {
if(cookies!=null){
for (Cookie c : cookies) {
//通过名称获取
if(name.equals(c.getName())){
//返回
return c;
}
}
}
return null;
}}
package com.javaweb.servlet;
import java.io.IOException;
import java.util.Arrays;
import java.util.LinkedList;
import java.util.List;import javax.servlet.ServletException;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;import com.javaweb.utils.CookUtils;
/**
* 记录商品浏览器历史
*/
public class GetProductByIDServlet extends HttpServlet {protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
//0.设置编码(这里不需要设置编码,获取的是word)
//0.1获取当前访问的商品id(给之前的每个商品设置id)
String id=request.getParameter("id");
//1.获取指定的cookie ids
Cookie c = CookUtils.getCookieByName("ids", request.getCookies());
String ids="";
//2.判断cookie是否为空
if(c==null){
//若cookie为空 需要将当前商品id放入ids中
ids=id;
}else{
//若cookie不为空 继续判断ids中是否已经该id // ids=2-11-21
//获取值
ids=c.getValue();
String[] arr = ids.split("-");
//将数组转成集合 此list长度不可变
ListasList = Arrays.asList(arr);
//将aslist放入一个新list中
LinkedListlist = new LinkedList<>(asList);
if(list.contains(id)){
//若ids中包含id 将id移除 放到最前面
list.remove(id);
list.addFirst(id);
}else{
//若ids中不包含id 继续判断长度是否大于2
if(list.size()>2){
//长度>=3 移除最后一个 将当前的放入最前面
list.removeLast();
list.addFirst(id);
}else{
//长度<3 将当前放入最前面
list.addFirst(id);
}
}
ids="";
//将list转成字符串
for (String s : list) {
ids+=(s+"-");
}
ids=ids.substring(0, ids.length()-1);
}
//将ids写回去
c=new Cookie("ids",ids);
//设置访问路径
c.setPath(request.getContextPath()+"/");
//设置存活时间
c.setMaxAge(3600);
//写会浏览器
response.addCookie(c);
//3.跳转到指定的商品页面上(product_info这里需要自己去修改)
response.sendRedirect(request.getContextPath()+"/product_info"+id+".htm");
}protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
doGet(request, response);
}}
package com.javaweb.servlet;
import java.io.IOException;
import javax.servlet.ServletException;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
public class CleanHistory extends HttpServlet {
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
//创建一个cookie
Cookie c=new Cookie("ids", "");
c.setPath(request.getContextPath()+"/");//
//设置时间
c.setMaxAge(0);
//写会浏览器
response.addCookie(c);
//页面跳转(product_list.jsp是需要自己写的)
response.sendRedirect(request.getContextPath()+"/product_list.jsp");
}protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
doGet(request, response);
}}
cookie不能跨浏览器
cookie中不支持中文
1.session介绍
Session是另一种记录客户状态的机制,不同的是Cookie保存在客户端浏览器中,而Session保存在服务器上。客户端浏览器访问服务器的时候,服务器把客户端信息以某种形式记录在服务器上。这就是Session。客户端浏览器再次访问时只需要从该Session中查找该客户的状态就可以了。
如果说Cookie机制是通过检查客户身上的“通行证”来确定客户身份的话,那么Session机制就是通过检查服务器上的“客户明细表”来确认客户身份。Session相当于程序在服务器上建立的一份客户档案,客户来访的时候只需要查询客户档案表就可以了。
2.获取session
HttpSession(返回值) request.getSession()
3.域对象
不错,session也是一个域对象,目前为止,学到现在,已经三个域对象了
ServletContext(全局)
Request(一次请求)
Session(私有)
xxxAttribute
生命周期:
创建:第一次调用request.getsession()创建
销毁:
1.服务器非正常关闭
2.session超时
默认时间超时:30分钟 web.xml有配置
手动设置超时:setMaxInactiveInterval(int 秒) 了解就可以了
3.手动干掉session
★session.invalidate()
session 存放的私有的数据. 一个浏览器一个session
需求:将商品添加到购物车
步骤分析:
1.点击添加到购物车的时候,提交到一个servlet add2CartServlet
需要将商品名称携带过去
2.add2CartServlet中的操作
获取商品的名称
将商品添加到购物车 购物车的结构 Map
将购物车放入session中就可以了
将商品添加到购物车分析:
获取购物车
判断购物车是否为空
若为空:
第一次添加
创建一个购物车
将当前商品put进去.数量:1
将购物车放入session中
若不为空:继续判断购物车中是否有该商品
若有:
取出count 将数量+1
将商品再次放入购物车中
若没有:
将当前商品put进去 数量:1
提示信息:你的xx已添加到购物车中
3.点击购物车连接的时候 cart.jsp
从session获取购物车
判断购物车是否为空
若为空:提示信息
若不为空:遍历购物车打印即可
代码如下:
package com.javaweb.addCart;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.HashMap;
import java.util.Map;import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;/**
*
*/
public class Add2Cart extends HttpServlet {
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
//0.设置编码
//对提示信息有用,这个设置编码对0步骤没用
response.setContentType("text/html;charset=utf-8");
PrintWriter w = response.getWriter();
//1.获取商品的名称(是汉字的话有可能是乱码)
String name=request.getParameter("name");
name=new String(name.getBytes("iso8859-1"),"utf-8");
//2.将商品添加到购物车
//2.1 从session中获取购物车
Mapmap=(Map ) request.getSession().getAttribute("cart");
Integer count=null;
//2.2判断购物车是否为空
if(map==null){
//第一次购物 创建购物车
map=new HashMap<>();
//将购物车放入session中g
request.getSession().setAttribute("cart", map);
count=1;
}else{
//购物车不为空 继续判断购物车中是否有该商品
count = map.get(name);
if(count==null){
//购物车中没有该商品
count=1;
}else{
//购物车中有该商品
count++;
}
}
//将商品放入购物车中
map.put(name, count);
//3.提示信息
w.print("已经将"+name+"添加到购物车中
");
w.print("继续购物 ");
w.print("查看购物车 ");
}
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
doGet(request, response);
}}
效果展示
2.点击妹子1
3.点击购物车
思路1:将购物车移除
思路2:将session干掉
步骤分析:
在cart.jsp上添加一个超链接 清空购物车
清空购物车
在clearCart中需要调用session.invalidate()
重定向到购物车页面
cart.jsp
<%@page import="java.util.Map"%><!--这个也是可以导入的-->
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
Insert title here
商品名称
商品数量
<%
//1.获取购物车
Mapmap=(Map )session.getAttribute("cart");
//2.判断购物车是否为空
if(map==null){
//2.1若为空 : 亲,购物车空空,先去逛逛~~
out.print(""); 亲,购物车空空,先去逛逛~~
}else{
//2.2若不为空 :遍历购物车
for(String name:map.keySet()){
out.print(""); ");
out.print(""); ");
out.print(name);
out.print("
out.print(""); ");
out.print(map.get(name));
out.print("
out.print("
}
}
%>
继续购物
清空购物车
ClearServlet
package com.itheima.web.servlet;
import java.io.IOException;
import javax.servlet.ServletException;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;/**
*清空浏览记录
*/
public class ClearHistroyServlet extends HttpServlet {
private static final long serialVersionUID = 1L;protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
//创建一个cookie
Cookie c=new Cookie("ids", "");
c.setPath(request.getContextPath()+"/");//
//设置时间
c.setMaxAge(0);
//写会浏览器
response.addCookie(c);
//页面跳转
response.sendRedirect(request.getContextPath()+"/product_list.jsp");
}protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
doGet(request, response);
}}
虽然Session保存在服务器,对客户端是透明的,它的正常运行仍然需要客户端浏览器的支持。这是因为Session 需要使用Cookie作为识别标志。HTTP协议是无状态的,Session不能依据HTTP连接来判断是否为同一客户,因此服务器向客户端浏览器发送一 个名为JSESSIONID的Cookie,它的值为该Session的id(也就是HttpSession.getId()的返回值)。Session 依据该Cookie来识别是否为同一用户。
该Cookie为服务器自动生成的,它的maxAge属性一般为–1,表示仅当前浏览器内有效,并且各浏览器窗口间不共享,关闭浏览器就会失效。
1、存放位置不同
Cookie保存在客户端,Session保存在服务端。
2 、存取方式的不同
Cookie中只能保管ASCII字符串,假如需求存取Unicode字符或者二进制数据,需求先进行编码。Cookie中也不能直接存取Java对象。若要存储略微复杂的信息,运用Cookie是比拟艰难的。
而Session中能够存取任何类型的数据,包括而不限于String、Integer、List、Map等。Session中也能够直接保管Java Bean乃至任何Java类,对象等,运用起来十分便当。能够把Session看做是一个Java容器类。
3、安全性(隐私策略)的不同
Cookie存储在浏览器中,对客户端是可见的,客户端的一些程序可能会窥探、复制以至修正Cookie中的内容。而Session存储在服务器上,对客户端是透明的,不存在敏感信息泄露的风险。 假如选用Cookie,比较好的方法是,敏感的信息如账号密码等尽量不要写到Cookie中。最好是像Google、Baidu那样将Cookie信息加密,提交到服务器后再进行解密,保证Cookie中的信息只要本人能读得懂。而假如选择Session就省事多了,反正是放在服务器上,Session里任何隐私都能够有效的保护。
4、有效期上的不同
只需要设置Cookie的过期时间属性为一个很大很大的数字,Cookie就可以在浏览器保存很长时间。 由于Session依赖于名为JSESSIONID的Cookie,而Cookie JSESSIONID的过期时间默许为–1,只需关闭了浏览器(一次会话结束),该Session就会失效。
5、对服务器造成的压力不同
Session是保管在服务器端的,每个用户都会产生一个Session。假如并发访问的用户十分多,会产生十分多的Session,耗费大量的内存。而Cookie保管在客户端,不占用服务器资源。假如并发阅读的用户十分多,Cookie是很好的选择。
6、 跨域支持上的不同
Cookie支持跨域名访问,例如将domain属性设置为“.baidu.com”,则以“.baidu.com”为后缀的一切域名均能够访问该Cookie。跨域名Cookie如今被普遍用在网络中。而Session则不会支持跨域名访问。Session仅在他所在的域名内有效。
可以参考下面博客:cookie和session的区别
http://blog.csdn.net/shuaishenkkk/article/details/8634917
为什么会有cookie呢,大家都知道,http是无状态的协议,客户每次读取web页面时,服务器都打开新的会话,而且服务器也不会自动维护客户的上下文信息,那么要怎么才能实现网上商店中的购物车呢,session就是一种保存上下文信息的机制,它是针对每一个用户的,变量的值保存在服务器端,通过 SessionID来区分不同的客户,session是以cookie或URL重写为基础的,默认使用cookie来实现,系统会创造一个名为 JSESSIONID的输出cookie,我们叫做session cookie,以区别persistent cookies,也就是我们通常所说的cookie,注意session cookie是存储于浏览器内存中的,并不是写到硬盘上的,这也就是我们刚才看到的JSESSIONID,我们通常情是看不到JSESSIONID的,但是当我们把浏览器的cookie禁止后,web服务器会采用URL重写的方式传递Sessionid,我们就可以在地址栏看到sessionid= KWJHUG6JJM65HS2K6之类的字符串。
明白了原理,我们就可以很容易的分辨出persistent cookies和session cookie的区别了,网上那些关于两者安全性的讨论也就一目了然了,session cookie针对某一次会话而言,会话结束session cookie也就随着消失了,而persistent cookie只是存在于客户端硬盘上的一段文本(通常是加密的),而且可能会遭到cookie欺骗以及针对cookie的跨站脚本攻击,自然不如 session cookie安全了。
通常session cookie是不能跨窗口使用的,当你新开了一个浏览器窗口进入相同页面时,系统会赋予你一个新的sessionid,这样我们信息共享的目的就达不到了,此时我们可以先把sessionid保存在persistent cookie中,然后在新窗口中读出来,就可以得到上一个窗口SessionID了,这样通过session cookie和persistent cookie的结合我们就实现了跨窗口的session tracking(会话跟踪)。
在一些web开发的书中,往往只是简单的把Session和cookie作为两种并列的http传送信息的方式,session cookies位于服务器端,persistent cookie位于客户端,可是session又是以cookie为基础的,明白的两者之间的联系和区别,我们就不难选择合适的技术来开发web service了。