4.1 会话机制
一次会话指的是:就好比打电话,A给B打电话,接通之后,会话开始,直到挂断电话,该次会话就结束了,而浏览器访问服务器,就跟打电话一样,浏览器A给服务器发送请求,访问web程序,该次会话就已经接通,其中不管浏览器发送多少请求(就相当于接通电话后说话一样),都视为一次会话,直到浏览器关闭,本次会话结束。同一台电脑用不同浏览器访问服务器,算作多次不同的访问。
常用的会话跟踪技术是Cookie与Session。Cookie通过在客户端记录信息确定用户身份,Session通过在服务器端记录信息确定用户身份。
假如一个咖啡店有喝5杯咖啡免费赠一杯咖啡的优惠,然而一次性消费5杯咖啡的机会微乎其微,这时就需要某种方式来纪录某位顾客的消费数量。想象一下其实也无外乎下面的几种方案:
1、该店的店员很厉害,能记住每位顾客的消费数量,只要顾客一走进咖啡店,店员就知道该怎么对待了。这种做法就是协议本身支持状态。但是http协议本身是无状态的
2、发给顾客一张卡片,上面记录着消费的数量,一般还有个有效期限。每次消费时,如果顾客出示这张卡片,则此次消费就会与以前或以后的消费相联系起来。这种做法就是在客户端保持状态。也就是cookie。 顾客就相当于浏览器,cookie如何工作,下面会详细讲解
3、发给顾客一张会员卡,除了卡号之外什么信息也不纪录,每次消费时,如果顾客出示该卡片,则店员在店里的纪录本上找到这个卡号对应的纪录添加一些消费信息。这种做法就是在服务器端保持状态。
由于HTTP协议是无状态的,而出于种种考虑也不希望使之成为有状态的,因此,后面两种方案就成为现实的选择。具体来说cookie机制采用的是在客户端保持状态的方案,而session机制采用的是在服务器端保持状态的方案。同时我们也看到,由于采用服务器端保持状态的方案在客户端也需要保存一个标识,所以session机制可能需要借助于cookie机制来达到保存标识的目的,但实际上它还有其他选择。
4.2 Cookie机制
如何分发会员卡,会员卡的内容,客户如何使用会员卡,会员卡的有效日期,会员卡的使用范围
1. 分发和会员卡内容
Cookie cookie = new Cookie(key,value); //以键值对的方式存放内容,
response.addCookie(cookie); //发送回浏览器端
// 一旦cookie创建好了,就不能在往其中增加别的键值对,但是可以修改其中的内容,
cookie.setValue(); //将key对应的value值修改
2. 客户如何使用会员卡,cookie在客户端是如何工作的,工作原理是什么?
3、会员卡的有效日期?也就是cookie也是拥有有效日期的。
cookie.setMaxAge(expiry); //设置cookie被浏览器保存的时间。
expiry:单位秒,默认为-1,
expiry=-1:代表浏览器关闭后,也就是会话结束后,cookie就失效了,也就没有了。
expiry>0:代表浏览器关闭后,cookie不会失效,仍然存在。并且会将cookie保存到硬盘中,直到设置时间过期才会被浏览器自动删除,
expiry=0:删除cookie。不管是之前的expiry=-1还是expiry>0,当设置expiry=0时,cookie都会被浏览器给删除。
4. 会员卡的使用范围?
cookie默认路径:当前访问的servlet父路径。
例如:http://localhost:8080/test01/a/b/c/SendCookieServlet
默认路径:/test01/a/b/c 也就是说,在该默认路径下的所有Servlet都能够获取到cookie,/test01/a/b/c/MyServlet 这个MyServlet就能获取到cookie。
修改cookie的访问路径
setPath("/"); //在该服务器下,任何项目,任何位置都能获取到cookie,
通途:保证在tomcat下所有的web项目可以共享相同的cookie
例如:tieba , wenku , beike 多个项目共享数据。例如用户名。
setPath("/test01/"); //在test01项目下任何位置都能获取到cookie。
5. 工作流程
工作流程:
- servlet创建cookie,保存少量数据,发送浏览器。
- 浏览器获得服务器发送的cookie数据,将自动的保存到浏览器端。
- 下次访问时,浏览器将自动携带cookie数据发送给服务器。
cookie操作
1.创建cookie:new Cookie(name,value)
2.发送cookie到浏览器:HttpServletResponse.addCookie(Cookie)
3.servlet接收cookie:HttpServletRequest.getCookies() 浏览器发送的所有cookie
cookie特点
- 每一个cookie文件大小:4kb , 如果超过4kb浏览器不识别
- 一个web站点(web项目):发送20个
3.一个浏览器保存总大小:300个
4.cookie 不安全,可能泄露用户信息。浏览器支持禁用cookie操作。 - 默认情况生命周期:与浏览器会话一样,当浏览器关闭时cookie销毁的。---临时cookie
cookie api
getName() 获得名称,cookie中的key
getValue() 获得值,cookie中的value
setValue(java.lang.String newValue) 设置内容,用于修改key对应的value值。
setMaxAge(int expiry) 设置有效时间【】
setPath(java.lang.String uri) 设置路径【】
setDomain(java.lang.String pattern) 设置域名 , 一般无效,有浏览器自动设置,setDomain(".itheima.com")
www.itheima.com / bbs.itheima.com 都可以访问
a.b.itheima.com无法访问
作用:设置cookie的作用范围,域名+路径在一起就构成了cookie的作用范围,上面单独设置的setPath有用,是因为有浏览器自动设置该域名属性,但是我们必须知道有这么个属性进行域名设置的
isHttpOnly() 是否只是http协议使用。只能servlet的通过getCookies()获得,javascript不能获得。
setComment(java.lang.String purpose) (了解) //对该cookie进行描述的信息(说明作用),浏览器显示cookie信息时能看到
setSecure(boolean flag) (了解) 是否使用安全传输协议。为true时,只有当是https请求连接时cookie才会发送给服务器端,而http时不会,但是服务端还是可以发送给浏览端的。
setVersion(int v) (了解) 参数为0(传统Netscape cookie规范编译)或1(RFC 2109规范编译)。这个没用到,不是很懂
注意:cookie不能发送中文,如果要发送中文,就需要进行特别处理。
JDK提供工具,进行编码
URLEncoder:编码
URLDecoder:解码
//发送cookie
Cookie cookie = new Cookie(URLEncoder.encode("哈哈"),URLEncoder.encode("呵呵"));
response.addCookie(cookie);
//获得cookie中文内容
URLDecoder.decoder(request.getCookie().getName); //获取key
三. Session
功能作用:服务器用于共享数据技术
1.创建过程
首先浏览器请求服务器访问web站点时,程序需要为客户端的请求创建一个session的时候,服务器首先会检查这个客户端请求是否已经包含了一个session标识、称为SESSIONID,
如果已经包含了一个sessionid则说明以前已经为此客户端创建过session,服务器就按照sessionid把这个session检索出来使用
如果客户端请求不包含session id,则服务器为此客户端创建一个session并且生成一个与此session相关联的session id
sessionid 的值应该是一个既不会重复,又不容易被找到规律以仿造的字符串,这个sessionid将在本次响应中返回到客户端保存,保存这个sessionid的方式就可以是cookie,这样在交互的过程中,浏览器可以自动的按照规则把这个标识发回给服务器,服务器根据这个sessionid就可以找得到对应的session,又回到了这段文字的开始。
2. 获取session
request.getSession(); //如果没有将创建一个新的,等效getSession(true);
3. set和get
用来存放一些信息,然后才能共享信息
setAttrubute(key,value);
getAttribute(key);
4. url重写
当浏览器将cookie禁用,基于cookie的session将不能正常工作,每次使用request.getSession() 都将创建一个新的session。达不到session共享数据的目的,但是我们知道原理,只需要将session id 传递给服务器session就可以正常工作的。
解决:通过URL将session id 传递给服务器:URL重写
手动方式: url;jsessionid=....
api方式:
encodeURL(java.lang.String url) 进行所有URL重写
encodeRedirectURL(java.lang.String url) 进行重定向 URL重写
这两个用法基本一致,只不过考虑特殊情况,要访问的链接可能会被Redirect到其他servlet去进行处理,这样你用上述方法带来的session的id信息不能被同时传送到其他servlet.这时候用encodeRedirectURL()方法就可以了
如果浏览器禁用cooke,api将自动追加session id ,如果没有禁用,api将不进行任何修改。
注意:如果浏览器禁用cookie,web项目的所有url都需进行重写。否则session将不能正常工作