java cookie共享_JavaWeb的session及其共享技术

原标题:JavaWeb的session及其共享技术

1.什么叫会话

一次会话指的是:就好比打电话,A给B打电话,接通之后,会话开始,直到挂断电话,该次会话就结束了,而浏览器访问服务器,就跟打电话一样,浏览器A给服务器发送请求,访问web程序,该次会话就已经接通,其中不管浏览器发送多少请求(就相当于接通电话后说话一样),都视为一次会话,直到浏览器关闭,本次会话结束。

其中注意,一个浏览器就相当于一部电话,如果使用火狐浏览器,访问服务器,就是一次会话了,然后打开google浏览器,访问服务器,这是另一个会话,虽然是在同一台电脑,同一个用户在访问,但是,这是两次不同的会话。

2.引入cookie和session

思考一个问题,一个浏览器访问一个服务器就能建立一个会话,如果别的电脑,都同时访问该服务器,就会创建很多会话,就拿一些购物网站来说,我们访问一个购物网站的服务器,会话就被创建了,然后就点击浏览商品,对感兴趣的商品就先加入购物车,等待一起付账,这看起来是很普通的操作,但是想一下,如果有很多别的电脑上的浏览器同时也在访问该购物网站的服务器,跟我们做类似的操作呢?服务器又是怎么记住用户,怎么知道用户A购买的任何商品都应该放在A的购物车内,不论是用户A什么时间购买的,不能放入用户B或用户C的购物车内的呢?

这里我们就用cookie和session两种会话跟踪技术来跟踪整个会话。

3.cookie简介

3.1.cookie的工作原理

a9bc8312ca86a6f9a3b013615097b854.png

1)首先浏览器向服务器发出请求。

2)服务器就会根据需要生成一个Cookie对象,并且把数据保存在该对象内。

3)然后把该Cookie对象放在响应头,一并发送回浏览器。

4)浏览器接收服务器响应后,提出该Cookie保存在浏览器端。

5)当下一次浏览器再次访问那个服务器,就会把这个Cookie放在请求头内一并发给服务器。

服务器从请求头提取出该Cookie,判别里面的数据,然后作出相应的动作。

3.2.cookie中的常用方法

Cookie cookie=new Cookie(String name,String value) 构造一个cookie对象

response.addCookie(Cookie cookie) 是将一个cookie对象传入客户端。

request.getCookies() 得到所有的cookie对象

cookie.getName() 得到此cookie对象的名字

cookie.getValue() 得到对应名称的cookie的值

cookie.setMaxAge() 设置过期时间

3.3.案例

1@WebServlet( "/CookieServletDemo1")

2publicclassCookieServletDemo1extendsHttpServlet{

3privatestaticfinallongserialVersionUID = 1L;

4

5/**

6* @seeHttpServlet#HttpServlet()

7*/

8publicCookieServletDemo1(){

9super();

10// TODO Auto-generated constructor stub

11}

12

13/**

14* @seeHttpServlet#doGet(HttpServletRequest request, HttpServletResponse

15* response)

16*/

17protectedvoiddoGet(HttpServletRequest request, HttpServletResponse response)

18throwsServletException, IOException {

19// 创建cookie对象

20// cookie中`存放的数据以键值对存在map 键和值都只能是字符串,不支持中文

21Cookie cookie = newCookie( "username", "zhangsan");

22Cookie cookie1 = newCookie( "password", "1234");

23// 失效时间 以秒为单位

24cookie.setMaxAge( 60* 60);

25response.addCookie(cookie);

26response.addCookie(cookie1);

27}

28

29/**

30* @seeHttpServlet#doPost(HttpServletRequest request, HttpServletResponse

31* response)

32*/

33protectedvoiddoPost(HttpServletRequest request, HttpServletResponse response)

34throwsServletException, IOException {

35// TODO Auto-generated method stub

36doGet(request, response);

37}

38

39}

1@WebServlet( "/CookieServletDemo2")

2publicclassCookieServletDemo2extendsHttpServlet{

3privatestaticfinallongserialVersionUID = 1L;

4

5/**

6* @seeHttpServlet#HttpServlet()

7*/

8publicCookieServletDemo2(){

9super();

10// TODO Auto-generated constructor stub

11}

12

13/**

14* @seeHttpServlet#doGet(HttpServletRequest request, HttpServletResponse

15* response)

16*/

17protectedvoiddoGet(HttpServletRequest request, HttpServletResponse response)

18throwsServletException, IOException {

19// 从请求头中获取cookie信息

20Cookie[] cookies = request.getCookies();

21for(Cookie c:cookies){

22System.out.println(c.getName()+ "===="+c.getValue());

23}

24}

25

26/**

27* @seeHttpServlet#doPost(HttpServletRequest request, HttpServletResponse

28* response)

29*/

30protectedvoiddoPost(HttpServletRequest request, HttpServletResponse response)

31throwsServletException, IOException {

32// TODO Auto-generated method stub

33doGet(request, response);

34}

35

36}

3.4.浏览器中查看cookie

不同的浏览器略有差别,这里以谷歌浏览器为例。

F12打开开发者工具 —点击Application选项—选中其中的cookie—选择相应的站点—看到该站点中的所有cookie信息。

3.5.cookie的应用场景

cookie的应用场景有很多,最具代表性的当属网站的记录用户账号和密码的功能了,大家可能经常看到登录某某论坛,某某网站时,下面有个选项为N天内自动登录,其实这就是cookie的应用。当用户第一次输入账号密码时给服务器发送请求时,服务器会根据账号密码回写一个字符串cookie,当用户下次再向该服务器发送登录请求时,则带着这个字符串cookie一起去访问服务器,这时,服务器只需要对比次字符串和数据库中存储的字符串是否相同,则可以达到用户自动登录功能。

3.6.cookie的局限性

Cookie数量和长度的限制。每个站点最多只能有20条cookie,每个cookie长度不能超过4KB,否则会被截掉。

cookie中只能存字符串。且不支持中文

cookie不适合保存敏感数据(例如密码)可见的

4.session

4.1.session的工作原理

274dbf61a0097a86a92a9a4593ce3da7.png

1)浏览器发出请求到服务器。

2)服务器会根据需求生成Session对象,并且给这个Session对象一个编号,一个编号对应一个Session对象

3)服务器把需要记录的数据封装到这个Session对象里,然后把这个Session对象保存下来。

4)服务器把这个Session对象的编号放到一个Cookie里,随着响应发送给浏览器

5)浏览器接收到这个cookie就会保存下来

6)当下一次浏览器再次请求该服务器服务,就会发送该Cookie

7)服务器得到这个Cookie,取出它的内容,它的内容就是一个Session的编号!!!

8)凭借这个Session编号找到对应的Session对象,然后利用该Session对象把保存的数据取出来!

4.2.session的常用方法

2429b04af89ce274e9df841551872c14.png

4.3.案例

1@WebServlet( "/SeesionServletDemo1")

2publicclassSeesionServletDemo1extendsHttpServlet{

3privatestaticfinallongserialVersionUID = 1L;

4

5/**

6* @seeHttpServlet#HttpServlet()

7*/

8publicSeesionServletDemo1(){

9super();

10// TODO Auto-generated constructor stub

11}

12

13/**

14* @seeHttpServlet#doGet(HttpServletRequest request, HttpServletResponse

15* response)

16*/

17protectedvoiddoGet(HttpServletRequest request, HttpServletResponse response)

18throwsServletException, IOException {

19

20// 创建session对象

21HttpSession session = request.getSession();

22System.out.println(session.getId());

23

24session.setAttribute( "name", "zhangsan");

25

26session.setAttribute( "student", newStudent( 1, "zhangsan", 12));

27Student stu = (Student) session.getAttribute( "student");

28

29stu.setName( "lisi");

30

31// 设置过期时间 单位是秒

32// session.setMaxInactiveInterval(2);

33// 直接销毁session 注销登录

34// session.invalidate();

35

36}

37

38/**

39* @seeHttpServlet#doPost(HttpServletRequest request, HttpServletResponse

40* response)

41*/

42protectedvoiddoPost(HttpServletRequest request, HttpServletResponse response)

43throwsServletException, IOException {

44// TODO Auto-generated method stub

45doGet(request, response);

46}

47

48}

1publicclassStudent{

2

3privateInteger id;

4privateString name;

5privateInteger age;

6publicInteger getId(){

7returnid;

8}

9publicvoidsetId(Integer id){

10this.id = id;

11}

12publicString getName(){

13returnname;

14}

15publicvoidsetName(String name){

16this.name = name;

17}

18publicInteger getAge(){

19returnage;

20}

21publicvoidsetAge(Integer age){

22this.age = age;

23}

24publicStudent(Integer id, String name, Integer age){

25super();

26this.id = id;

27this.name = name;

28this.age = age;

29}

30publicStudent(){

31super();

32// TODO Auto-generated constructor stub

33}

34}

1@WebServlet( "/SeesionServletDemo2")

2publicclassSeesionServletDemo2extendsHttpServlet{

3privatestaticfinallongserialVersionUID = 1L;

4

5/**

6* @seeHttpServlet#HttpServlet()

7*/

8publicSeesionServletDemo2(){

9super();

10// TODO Auto-generated constructor stub

11}

12

13/**

14* @seeHttpServlet#doGet(HttpServletRequest request, HttpServletResponse

15* response)

16*/

17protectedvoiddoGet(HttpServletRequest request, HttpServletResponse response)

18throwsServletException, IOException {

19

20// 创建session对象

21HttpSession session = request.getSession();

22

23System.out.println(session.getAttribute( "name"));

24

25Student stu = (Student) session.getAttribute( "student");

26System.out.println(stu.getName());

27

28}

29

30/**

31* @seeHttpServlet#doPost(HttpServletRequest request, HttpServletResponse

32* response)

33*/

34protectedvoiddoPost(HttpServletRequest request, HttpServletResponse response)

35throwsServletException, IOException {

36// TODO Auto-generated method stub

37doGet(request, response);

38}

39

40}

4.4.session的生命周期

session对象生命周期:

session对象什么创建?

执行request.getSession()方法时

session对象什么销毁?

①默认情况下,session对象在30分钟之后服务器自动销毁。

②手动设置session有效时长

void setMaxInactiveInterval(int interval) -以秒为单位。

③手动销毁

void invalidate()

4.5.session在一次会话结束后消失的原因

由于session的使用需要依赖cookie,cookie每次从浏览器端传输session的id到后台,然后查找对应编号的session进行使用,但由于此时的cookie默认的失效时间是一次会话,当一次会话结束后,存放id的cookie对象就消失了,下一次会话访问时就会生成新的id,那存储在原来的session对象中的数据就无法找到了。

4.6.浏览器禁用cookie能否使用session

可以,但需要手动拼接id传过去,例如

1http: //localhost:8080/day06/session.jsp;jsessionid=AE62ECBAAD2CA16DA6AEBF1D1527CD45

jsessionid指的就是session对应的id

4.7.session共享

4.7.1.基于数据库的Session共享

首选当然是大名鼎鼎的Mysql数据库,并且建议使用内存表Heap,提高session操作的读写效率。这个方案的实用性比较强,相信大家普遍在使用,它的缺点在于session的并发读写能力取决于Mysql数据库的性能,同时需要自己实现session淘汰逻辑,以便定时从数据表中更新、删除 session记录,当并发过高时容易出现表锁,虽然我们可以选择行级锁的表引擎,但不得不否认使用数据库存储Session还是有些杀鸡用牛刀的架势。

4.7.2.基于Cookie的Session共享

这个方案我们可能比较陌生,但它在大型网站中还是比较普遍被使用。原理是将全站用户的Session信息加密、序列化后以Cookie的方式, 统一种植在根域名下(如:.host.com),利用浏览器访问该根域名下的所有二级域名站点时,会传递与之域名对应的所有Cookie内容的特性,从而实现 用户的Cookie化Session 在多服务间的共享访问。

这个方案的优点无需额外的服务器资源;缺点是由于受http协议头信心长度的限制,仅能够存储小部分的用户信息,同时Cookie化的 Session内容需要进行安全加解密(如:采用DES、RSA等进行明文加解密;再由MD5、SHA-1等算法进行防伪认证),另外它也会占用一定的带宽资源,因为浏览器会在请求当前域名下任何资源时将本地Cookie附加在http头中传递到服务器。

4.7.3.基于Memcache的Session共享

Memcache由于是一款基于Libevent多路异步I/O技术的内存共享系统,简单的Key + Value数据存储模式使得代码逻辑小巧高效,因此在并发处理能力上占据了绝对优势,目前本人所经历的项目达到2000/秒 平均查询,并且服务器CPU消耗依然不到10%。

另外值得一提的是Memcache的内存hash表所特有的Expires数据过期淘汰机制,正好和Session的过期机制不谋而合,降低了 过期Session数据删除的代码复杂度,对比“基于数据库的存储方案”,仅这块逻辑就给数据表产生巨大的查询压力。

更多资深讲师相关课程资料、学习笔记请入群后向管理员免费获取,更有专业知识答疑解惑。入群即送价值499元在线课程一份。

QQ群号:560819979

敲门砖(验证信息):醉渔唱晚返回搜狐,查看更多

责任编辑:

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值