Fork me on GitHub

java基础学习:JavaWeb之Cookie和Session

一、会话概述

1.1、什么是会话?

会话可简单理解为:用户开一个浏览器,点击多个超链接,访问服务器多个web资源,然后关闭浏览器,整个过程称之为一个会话其中不管浏览器发送多少请求,都视为一次会话,直到浏览器关闭,本次会话结束。
其中注意,一个浏览器就相当于一部电话,如果使用火狐浏览器,访问服务器,就是一次会话了,然后打开google浏览器,访问服务器,这是另一个会话,虽然是在同一台电脑,同一个用户在访问,但是,这是两次不同的会话。

1.2、会话机制

  Web程序中常用的技术,用来跟踪用户的整个会话。常用的会话跟踪技术是Cookie与Session。Cookie通过在客户端记录信息确定用户身份,Session通过在服务器端记录信息确定用户身份。

二、Cookie

Cookie是客户端技术,程序把每个用户的数据以cookie的形式写给用户各自的浏览器。当用户使用浏览器再去访问服务器中的web资源时,就会带着各自的数据去。这样,web资源处理的就是用户各自的数据了。由于cookie是由客户端浏览器保存和携带的,所以称之为客户端技术

2.1、Cookie的工作流程

1)servlet创建cookie,保存少量数据,发送浏览器。
2)浏览器获得服务器发送的cookie数据,将自动的保存到浏览器端。
3)下次访问时,浏览器将自动携带cookie数据发送给服务器。

2.2、Cookie特点

1)每一个cookie文件大小:4kb , 如果超过4kb浏览器不识别
2)一个web站点(web项目):发送20个
3)一个浏览器保存总大小:300个
4)cookie 不安全,可能泄露用户信息。浏览器支持禁用cookie操作。
5) 默认情况生命周期:与浏览器会话一样,当浏览器关闭时cookie销毁的。---临时cookie

cookie.setMaxAge(expiry);  //设置cookie被浏览器保存的时间。
      
expiry:单位秒,默认为-1,
expiry=-1:代表浏览器关闭后,也就是会话结束后,cookie就失效了,也就没有了。
expiry>0:代表浏览器关闭后,cookie不会失效,仍然存在。并且会将cookie保存到硬盘中,直到设置时间过期才会被浏览器自动删除,
expiry=0:删除cookie。不管是之前的expiry=-1还是expiry>0,当设置expiry=0时,cookie都会被浏览器给删除。
复制代码

2.3、Cookie操作

操作cookie

  1)创建cookie:new Cookie(name,value)
  2)发送cookie到浏览器:HttpServletResponse.addCookie(Cookie)
  3)servlet接收cookie:HttpServletRequest.getCookies() 浏览器发送的所有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(".zyh.com")
    www.zyh.com / bbs.zyh.com 都可以访问
    a.b.zyh.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不能发送中文,如果要发送中文,就需要进行特别处理。

Cookie cookie = new Cookie("country", URLEncoder.encode("中国", "UTF-8"));
response.addCookie(cookie);

//经过URLEncoding就要URLDecoding
String value = URLDecoder.decode(cookies[i].getValue(), "UTF-8");
复制代码

三、Session

在WEB开发中,服务器可以为每个用户浏览器创建一个会话对象(session对象),注意:一个浏览器独占一个session对象(默认情况下)
因此,在需要保存用户数据时,服务器程序可以把用户数据写到用户浏览器独占的session中,当用户使用浏览器访问其它程序时,其它程序可以从用户的session中取出该用户的数据,为用户服务。

3.1、Session的原理

  1. 首先浏览器请求服务器访问web站点时,程序需要为客户端的请求创建一个session的时候,服务器首先会检查这个客户端请求是否已经包含了一个session标识、称为SESSIONID
  2. 如果已经包含了一个sessionid则说明以前已经为此客户端创建过session,服务器就按照sessionid把这个session检索出来使用,如果客户端请求不包含session id,则服务器为此客户端创建一个session并且生成一个与此session相关联的session id,sessionid 的值应该是一个既不会重复,又不容易被找到规律以仿造的字符串,这个sessionid将在本次响应中返回到客户端保存,保存这个sessionid的方式一般就是cookie。
  3. 这样在交互的过程中,浏览器可以自动的按照规则把这个标识发回给服务器,服务器根据这个sessionid就可以找得到对应的session,又回到了步骤1。

3.2、Session的生命周期

常常听到这样一种误解“只要关闭浏览器,session就消失了”。其实可以想象一下会员卡的例子,除非顾客主动对店家提出销卡,否则店家绝对不会轻易删除顾客的资料。对session来说也是一样的,除非程序通知服务器删除一个session,否则服务器会一直保留,程序一般都是在用户做log off的时候发个指令去删除session。然而浏览器从来不会主动在关闭之前通知服务器它将要关闭,因此服务器根本不会有机会知道浏览器已经关闭,之所以会有这种错觉,是大部分session机制都使用会话cookie来保存session id,而关闭浏览器后这个session id就消失了,再次连接服务器时也就无法找到原来的session。如果服务器设置的cookie被保存到硬盘上,或者使用某种手段改写浏览器发出的HTTP请求头,把原来的session id发送给服务器,则再次打开浏览器仍然能够找到原来的session。

恰恰是由于关闭浏览器不会导致session被删除,迫使服务器为seesion设置了一个失效时间,一般是30分钟,当距离客户端上一次使用session的时间超过这个失效时间时,服务器就可以认为客户端已经停止了活动,才会把session删除以节省存储空间。Session生成后,只要用户继续访问,服务器就会更新Session的最后访问时间,无论是否对Session进行读写,服务器都会认为Session活跃了一次,重新开始计算失效时间。

我们也可以自己来控制session的有效时间:

session.invalidate()将session对象销毁
setMaxInactiveInterval(int interval) 设置有效时间,单位秒
复制代码

在web.xml中配置session的有效时间: 

<session-config>
<session-timeout>30</session-timeout> 单位:分钟 
<session-config>
复制代码

所以,讨论了这么久,session的生命周期就是:
创建:Session存储在服务器端,一般放置在服务器的内存中(为了高速存取),Sessinon在用户访问第一次访问服务器时创建,需要注意只有访问JSP、Servlet等程序时才会创建Session,只访问HTML、IMAGE等静态资源并不会创建Session,可调用request.getSession(true)强制生成Session。
销毁
1)超时,默认30分钟
2)执行api:session.invalidate()将session对象销毁、setMaxInactiveInterval(int interval) 设置有效时间,单位:秒
3)服务器非正常关闭(自杀,直接将JVM马上关闭)
如果正常关闭,session就会被持久化(写入到文件中,因为session默认的超时时间为30分钟,正常关闭后,就会将session持久化,等30分钟后,就会被删除)
位置: D:\java\tomcat\apache-tomcat-7.0.53\work\Catalina\localhost\test01\SESSIONS.ser

3.3、session id的URL重写

当浏览器将cookie禁用,基于cookie的session将不能正常工作,每次使用request.getSession() 都将创建一个新的session。达不到session共享数据的目的,但是我们知道原理,只需要将session id 传递给服务器session就可以正常工作的。
解决:通过URL将session id 传递给服务器:URL重写
1)手动方式: url;jsessionid=....
2)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将不能正常工作。
当cookie禁用时:

image.png

 

四、Session和Cookie的区别

4.1、从存储方式上比较

Cookie只能存储字符串,如果要存储非ASCII字符串还要对其编码。
Session可以存储任何类型的数据,可以把Session看成是一个容器

4.2、从隐私安全上比较

Cookie存储在浏览器中,对客户端是可见的。信息容易泄露出去。如果使用Cookie,最好将Cookie加密
Session存储在服务器上,对客户端是透明的。不存在敏感信息泄露问题。

4.3、从有效期上比较

Cookie保存在硬盘中,只需要设置maxAge属性为比较大的正整数,即使关闭浏览器,Cookie还是存在的
Session的保存在服务器中,设置maxInactiveInterval属性值来确定Session的有效期。并且Session依赖于名为JSESSIONID的Cookie,该Cookie默认的maxAge属性为-1。如果关闭了浏览器,该Session虽然没有从服务器中消亡,但也就失效了。

4.4、从对服务器的负担比较

Session是保存在服务器的,每个用户都会产生一个Session,如果是并发访问的用户非常多,是不能使用Session的,Session会消耗大量的内存。
Cookie是保存在客户端的。不占用服务器的资源。像baidu、Sina这样的大型网站,一般都是使用Cookie来进行会话跟踪。

4.5、从浏览器的支持上比较

如果浏览器禁用了Cookie,那么Cookie是无用的了!
如果浏览器禁用了Cookie,Session可以通过URL地址重写来进行会话跟踪。

4.6、从跨域名上比较

Cookie可以设置domain属性来实现跨域名
Session只在当前的域名内有效,不可夸域名


作者:Hiway
链接:https://juejin.im/post/5c160421e51d457e9f28a134

posted @ 2018-12-18 15:11  梳碧湖砍柴的人  阅读(192)  评论(0编辑  收藏  举报