一.会话
一次会话指的是:就好比打电话,A给B打电话,接通之后,会话开始,直到挂断电话,该次会话就结束了,而浏览器访问服务器,就跟打电话一样,浏览器A给服务器发送请求,访问web程序,该次会话就已经接通,其中不管浏览器发送多少请求(就相当于接通电话后说话一样),都视为一次会话,直到浏览器关闭,本次会话结束。其中注意,一个浏览器就相当于一部电话,如果使用火狐浏览器,访问服务器,就是一次会话了,然后打开google浏览器,访问服务器,这是另一个会话,虽然是在同一台电脑,同一个用户在访问,但是,这是两次不同的会话。
Web程序中常用的技术,用来跟踪用户的整个会话。常用的会话跟踪技术是Cookie与Session。Cookie通过在客户端记录信息确定用户身份,Session通过在服务器端记录信息确定用户身份。
Cookie是客户端技术,程序把每个用户的数据以cookie的形式写给用户各自的浏览器。当用户使用浏览器再去访问服务器中的web资源时,就会带着各自的数据去。这样,web资源处理的就是用户各自的数据了。
Session是服务器端技术,利用这个技术,服务器在运行时可以为每一个用户的浏览器创建一个其独享的session对象,由于session为用户浏览器独享,所以用户在访问服务器的web资源时,可以把各自的数据放在各自的session中,当用户再去访问服务器中的其它web资源时,其它web资源再从用户各自的session中取出数据为用户服务。
Cookie和Session之间的区别和联系
假如一个咖啡店有喝5杯咖啡免费赠一杯咖啡的优惠,然而一次性消费5杯咖啡的机会微乎其微,这时就需要某种方式来纪录某位顾客的消费数量。想象一下其实也无外乎下面的几种方案:
1、该店的店员很厉害,能记住每位顾客的消费数量,只要顾客一走进咖啡店,店员就知道该怎么对待了。这种做法就是协议本身支持状态。但是http协议本身是无状态的
2、发给顾客一张卡片,上面记录着消费的数量,一般还有个有效期限。每次消费时,如果顾客出示这张卡片,则此次消费就会与以前或以后的消费相联系起来。这种做法就是在客户端保持状态。也就是cookie。 顾客就相当于浏览器,cookie如何工作,下面会详细讲解
3、发给顾客一张会员卡,除了卡号之外什么信息也不纪录,每次消费时,如果顾客出示该卡片,则店员在店里的纪录本上找到这个卡号对应的纪录添加一些消费信息。这种做法就是在服务器端保持状态。
由于HTTP协议是无状态的,而出于种种考虑也不希望使之成为有状态的,因此,后面两种方案就成为现实的选择。具体来说cookie机制采用的是在客户端保持状态的方案,而session机制采用的是在服务器端保持状态的方案。同时我们也看到,由于采用服务器端保持状态的方案在客户端也需要保存一个标识,所以session机制可能需要借助于cookie机制来达到保存标识的目的,但实际上它还有其他选择
二.cookie
Cookie类的主要方法:
名称 | 描述 |
---|---|
Cookie(String name, String value) | 实例化Cookie对象,传入cooke名称和cookie的值 |
public String getName() | 取得Cookie的名字 |
public String getValue() | 取得Cookie的值 |
public void setValue(String newValue) | 设置Cookie的值 |
public void setMaxAge(int expiry) | 设置Cookie的最大保存时间,即cookie的有效期 |
public int getMaxAge() | 获取Cookies的有效期 |
public void setPath(String uri) | 设置cookie的有效路径 |
public String getPath() | 获取cookie的有效路径 |
response接口也中定义了一个addCookie方法,它用于在其响应头中增加一个相应的Set-Cookie头字段。 同样,request接口中也定义了一个getCookies方法,它用于获取客户端提交的Cookie。
有效期:
cookie.setMaxAge(expiry); //设置cookie被浏览器保存的时间。
expiry:单位秒,默认为-1,
expiry=-1:代表浏览器关闭后,也就是会话结束后,cookie就失效了,也就没有了。
expiry>0:代表浏览器关闭后,cookie不会失效,仍然存在。并且会将cookie保存到硬盘中,直到设置时间过期才会被浏览器自动删除,
expiry=0:删除cookie。不管是之前的expiry=-1还是expiry>0,当设置expiry=0时,cookie都会被浏览器给删除。
当服务器给浏览器回送一个cookie时,如果在服务器端没有调用setMaxAge方法设置cookie的有效期,那么cookie的有效期只在一次会话过程中有效,用户开一个浏览器,点击多个超链接,访问服务器多个web资源,然后关闭浏览器,整个过程称之为一次会话,当用户关闭浏览器,会话就结束了,此时cookie就会失效,如果在服务器端使用setMaxAge方法设置了cookie的有效期,比如设置了30分钟,那么当服务器把cookie发送给浏览器时,此时cookie就会在客户端的硬盘上存储30分钟,在30分钟内,即使浏览器关了,cookie依然存在,在30分钟内,打开浏览器访问服务器时,浏览器都会把cookie一起带上,这样就可以在服务器端获取到客户端浏览器传递过来的cookie里面的信息了,这就是cookie设置maxAge和不设置maxAge的区别,不设置maxAge,那么cookie就只在一次会话中有效,一旦用户关闭了浏览器,那么cookie就没有了,那么浏览器是怎么做到这一点的呢,我们启动一个浏览器,就相当于启动一个应用程序,而服务器回送的cookie首先是存在浏览器的缓存中的,当浏览器关闭时,浏览器的缓存自然就没有了,所以存储在缓存中的cookie自然就被清掉了,而如果设置了cookie的有效期,那么浏览器在关闭时,就会把缓存中的cookie写到硬盘上存储起来,这样cookie就能够一直存在了。
有效路径:
setPath(String uri) ;//设置有效路径
比如把cookie的有效路径设置为"/xdp",那么浏览器访问"xdp"目录下的web资源时,都会带上cookie,再比如把cookie的有效路径设置为"/xdp/gacl",那么浏览器只有在访问"xdp"目录下的"gacl"这个目录里面的web资源时才会带上cookie一起访问,而当访问"xdp"目录下的web资源时,浏览器是不带cookie的
实例:
使用cookie记录上一次访问网站的时间
12 /**
13 * @author gacl
14 * cookie实例:获取用户上一次访问的时间
15 */
16 public class CookieDemo01 extends HttpServlet {
17
18 public void doGet(HttpServletRequest request, HttpServletResponse response)
19 throws ServletException, IOException {
20 //设置服务器端以UTF-8编码进行输出
21 response.setCharacterEncoding("UTF-8");
22 //设置浏览器以UTF-8编码进行接收,解决中文乱码问题
23 response.setContentType("text/html;charset=UTF-8");
24 PrintWriter out = response.getWriter();
25 //获取浏览器访问访问服务器时传递过来的cookie数组
26 Cookie[] cookies = request.getCookies();
27 //如果用户是第一次访问,那么得到的cookies将是null
28 if (cookies!=null) {
29 out.write("您上次访问的时间是:");
30 for (int i = 0; i < cookies.length; i++) {
31 Cookie cookie = cookies[i];
32 if (cookie.getName().equals("lastAccessTime")) {
33 Long lastAccessTime =Long.parseLong(cookie.getValue());
34 Date date = new Date(lastAccessTime);
35 out.write(date.toLocaleString());
36 }
37 }
38 }else {
39 out.write("这是您第一次访问本站!");
40 }
41
42 //用户访问过之后重新设置用户的访问时间,存储到cookie中,然后发送到客户端浏览器
43 Cookie cookie = new Cookie("lastAccessTime", System.currentTimeMillis()+"");//创建一个cookie,cookie的名字是lastAccessTime
//设置有效期为一天
cookie.setMaxAge(24*60*60);
44 //将cookie对象添加到response对象中,这样服务器在输出response对象中的内容时就会把cookie也输出到客户端浏览器
45 response.addCookie(cookie);
46 }
47
48 public void doPost(HttpServletRequest request, HttpServletResponse response)
49 throws ServletException, IOException {
50 doGet(request, response);
51 }
52
53 }
cookie总结:
工作流程:
-
servlet创建cookie,保存少量数据,发送浏览器。
-
浏览器获得服务器发送的cookie数据,将自动的保存到浏览器端。
-
下次访问时,浏览器将自动携带cookie数据发送给服务器。
cookie操作
-
创建cookie:new Cookie(name,value)
-
发送cookie到浏览器:HttpServletResponse.addCookie(Cookie)
-
servlet接收cookie:HttpServletRequest.getCookies() 浏览器发送的所有cookie
cookie特点
-
每一个cookie文件大小:4kb , 如果超过4kb浏览器不识别
-
一个web站点(web项目):发送20个
-
一个浏览器保存总大小:300个
-
cookie 不安全,可能泄露用户信息。浏览器支持禁用cookie操作。
-
默认情况生命周期:与浏览器会话一样,当浏览器关闭时cookie销毁的。—临时cookie
三. session
原理:
首先浏览器请求服务器访问web站点时,程序需要为客户端的请求创建一个session的时候,服务器首先会检查这个客户端请求是否已经包含了一个session标识、称为SESSIONID,如果已经包含了一个sessionid则说明以前已经为此客户端创建过session,服务器就按照sessionid把这个session检索出来使用,如果客户端请求不包含session id,则服务器为此客户端创建一个session并且生成一个与此session相关联的session id,sessionid 的值应该是一个既不会重复,又不容易被找到规律以仿造的字符串,这个sessionid将在本次响应中返回到客户端保存,保存这个sessionid的方式就可以是cookie,这样在交互的过程中,浏览器可以自动的按照规则把这个标识发回给服务器,服务器根据这个sessionid就可以找得到对应的session,又回到了这段文字的开始。
获取session:
request.getSession(); //如果没有将创建一个新的,等效getSession(true);
为什么是通过request来获取session,在获取session时,需要检测请求中是否有session标识,所以需要用request来获取
request.getSession(boolean); //true:没有将创建,false:没有将返回null
session对象的创建时机:
在程序中第一次调用request.getSession()方法时就会创建一个新的Session,可以用isNew()方法来判断Session是不是新创建的
session对象的销毁时机
session对象默认30分钟没有使用,则服务器会自动销毁session,在web.xml文件中可以手工配置session的失效时间,例如:
<!-- 设置Session的有效时间:以分钟为单位-->
<session-config>
<session-timeout>15</session-timeout>
</session-config>
当需要在程序中手动设置Session失效时,可以手工调用session.invalidate方法,摧毁session。
1 HttpSession session = request.getSession();
2 //手工调用session.invalidate方法,摧毁session
3 session.invalidate();
四.URL重写
浏览器禁用cookie:
参考文章:
https://www.cnblogs.com/whgk/p/6422391.html
https://www.cnblogs.com/xdp-gacl/p/3855702.html
https://www.cnblogs.com/xdp-gacl/p/3803033.html