一、会话概述

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禁用时:

四、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

java基础学习:JavaWeb之Cookie和Session的更多相关文章

  1. JAVA基础之会话技术-Cookie及Session

    至此,学习Servlet三个域对象:ServletContext(web项目).request(一次请求).Session(一个客户端)!均有相同的方法! 从用户开始打开浏览器进行操作,便开始了一次会 ...

  2. Java基础及JavaWEB以及SSM框架学习笔记Xmind版

    Java基础及JavaWEB以及SSM框架学习笔记Xmind版 转行做程序员也1年多了,最近开始整理以前学习过程中记录的笔记,以及一些容易犯错的内容.现在分享给网友们.笔记共三部分. JavaSE 目 ...

  3. JAVA基础学习-集合三-Map、HashMap,TreeMap与常用API

    森林森 一份耕耘,一份收获 博客园 首页 新随笔 联系 管理 订阅 随笔- 397  文章- 0  评论- 78  JAVA基础学习day16--集合三-Map.HashMap,TreeMap与常用A ...

  4. java的会话管理:Cookie和Session

    java的会话管理:Cookie和Session 1.什么是会话 此处的是指客户端(浏览器)和服务端之间的数据传输.例如用户登录,购物车等 会话管理就是管理浏览器客户端和服务端之间会话过程产生的会话数 ...

  5. Java基础学习-- 继承 的简单总结

    代码参考:Java基础学习小记--多态 为什么要引入继承? 还是做一个媒体库,里面可以放CD,可以放DVD.如果把CD和DVD做成两个没有联系的类的话,那么在管理这个媒体库的时候,要单独做一个添加CD ...

  6. Java基础学习中一些词语和语句的使用

    在Java基础学习中,我们刚接触Java会遇到一些词和语句的使用不清的情况,不能很清楚的理解它的运行效果会是怎么样的,如:break,continue在程序中运行效果及跳转位置, 1.先来看看brea ...

  7. Java基础学习笔记总结

    Java基础学习笔记一 Java介绍 Java基础学习笔记二 Java基础语法之变量.数据类型 Java基础学习笔记三 Java基础语法之流程控制语句.循环 Java基础学习笔记四 Java基础语法之 ...

  8. 转载-java基础学习汇总

    共2页: 1 2 下一页  Java制作证书的工具keytool用法总结 孤傲苍狼 2014-06-24 11:03 阅读:25751 评论:3     Java基础学习总结——Java对象的序列化和 ...

  9. java基础学习总结——开篇

    java是我学习的第一门编程语言,当初学习java基础的时候下了不少功夫,趁着这段时间找工作之际,好好整理一下以前学习java基础时记录的笔记,当作是对java基础学习的一个总结吧,将每一个java的 ...

  10. Java基础学习笔记(一)

    Java基础学习笔记(一) Hello World 基础代码学习 代码编写基础结构 class :类,一个类即一个java代码,形成一个class文件,写于每个代码的前端(注意无大写字母) XxxYy ...

随机推荐

  1. apache重写规则 rewrite

    Rewrite规则表达式的说明: . 匹配任何单字符 [chars] 匹配字符串:chars [^chars] 不匹配字符串:chars text1|text2 可选择的字符串:text1或text2 ...

  2. Sql Server外键约束

    一.添加约束(级联删除) 1.创建表结构时添加 create table UserDetails(id int identity(1,1) primary key,name varchar(50) n ...

  3. [转帖] .net 2.1 是 LTS长期支持版本.

    [翻译] .NET Core 2.1 发布   原文: Announcing .NET Core 2.1 我们很高兴可以发布 .NET Core 2.1.这次更新包括对性能的改进,对运行时和工具的改进 ...

  4. Python 字节码是什么

    了解 Python 字节码是什么,Python 如何使用它来执行你的代码,以及知道它是如何帮到你的. 如果你曾经编写过 Python,或者只是使用过 Python,你或许经常会看到 Python 源代 ...

  5. python 查看与更换工作目录

    1. 进入python控制台 2. 查看工作路径,需要导入os包: import os 3. 查看工作路径的命令: os.getcwd() 4. 修改工作路径的命令: os.chdir("d ...

  6. 在HL引擎中制作自定义高清贴花

    你是不是想过要做自定义的子弹孔.喷漆或者一些自定义的痕迹呢? 如果按照HL引擎的基本FA,首先要在decals.wad里加入我们自定义的纹理,然后利用gEngfuncs.pEfxAPI->R_D ...

  7. Linux_MySql_yum_安装

    1.卸载原始mysql-lib sudo rpm -e --nodeps mysql-libs-xx 2.yum安装mysql-server sudo yum -y install mysql -se ...

  8. 016 Java中的动态代理

    作者:nnngu GitHub:https://github.com/nnngu 博客园:http://www.cnblogs.com/nnngu 简书:https://www.jianshu.com ...

  9. python读取写入内存方法SringIO,BytesIO

    python中不仅仅可以在磁盘中写入文件,还允许直接在内存中直接写入数据:需要借助StringIO和BytesIO来实现: 1.直接操作StringIO from io import StringIO ...

  10. 使用SUID二进制文件进行Linux权限升级技巧

      0x00 基础知识 众所周知,在Linux中一切都以文件存在,包括具有允许或限制三个执行操作(即读/写/执行)权限的目录和设备.因此,当给任何文件设置权限时,应该需要了解允许的Linux用户或限制 ...