博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
《Head First Servlets & JSP》-6-会话管理
阅读量:5243 次
发布时间:2019-06-14

本文共 2473 字,大约阅读时间需要 8 分钟。

容器怎么知道客户是谁

Http协议是无状态连接,客户浏览器与服务器建立连接、发出请求、得到响应,然后关闭连接。即,连接只针对一个请求/响应。

对容器而言,每个请求都来自于一个新的客户。

客户需要一个唯一的会话ID

IP不能唯一标示Internet上特定的用户

比如公司网络内的用户为一个IP;而IP地址也只是路由的地址;用户换了一台设备的情况;

  • 客户和容器如何交互会话ID信息
    容器必须以某种方式吧会话ID作为响应的一部分交给客户,而客户必须把会话ID作为请求的一部分发回;
    最简单而且最常用的方式是通过cookie交换这个会话ID信息。
    容器会做cookie所有的工作!
    在响应中发送一个会话cookie:
    HttpSession session=request.geteSession();
    余下的所有事情都会自动发生:
    你不用自己建立新的HttpSession对象;
    你不必生成唯一的会话ID;
    你不用自己建立新的Cookie对象;
    你不用把会话ID与cookie关联;
    你不用在响应中设置Cookie;
    cookie的所有工作都在后台运行;

从请求得到会话ID:

HttpSession session=request.geteSession();
与为响应生成会话ID和cookie时所用的方法完全一样!
即:

 
  1. if(请求包含一个会话ID cookie){
  2. 找到与该ID匹配的会话;
  3. }else if(没有会话ID cookie OR 没有与此会话ID匹配的当前会话){
  4. 创建一个新会话;
  5. }
  • 若不想新建会话

    HttpSession session= request.getSession(false);
    若只想要一个已经有的会话,若没有会话则返回null,若有会话存在则返回HttpSession。

  • 若用户不接受cookie

    若用户没有启用cookie,则需要使用URL重写。在Tomcat中表现为URL+;jsessionid=1234567。
    如果不能用cookie,而且只要告诉响应要对URL编码,URL重写才能奏效。

    容器怎么知道cookie不能正常工作?

    容器并不知道cookie是否工作,所以向客户返回第一个响应时,它会同时尝试cookie和URL重写这两种方式;
    当用户发出下一个请求,它把会话ID追加到请求URL,若用户接受cookie,这个请求也会有一个会话ID cookie;
    当servlet调用request.getSession()时,容器若从请求读取会话ID,则认为这个客户接受cookie,所以可以忽略response.encodeURL()调用。

  • 另一种URL重写

    response.encodeRedirectURL("/BeerTest.do");
    用于想把请求重定向到另一个URL,但是还是想使用一个会话。

    注意,若依赖会话,就要把URL重写作为一条后路;

    另外,因为需要URL重写,就必须在响应HTML中动态生成URL,这意味着必须在运行时处理HTML。(当然,可以在JSP中完成URL重写。)
    encodeURL()方法是HttpServletResponse对象上调用的方法,不能再请求上调用这个方法;URL编码只与响应有关。

关键的HttpSession方法

设置会话超时

  • 会话有3中死法:
 
  1. 超时
  2. 在会话对象上调用invalidate()
  3. 应用结束(崩溃或取消部署)
  • 在DD中配置会话超时
    这与在会话上调用setMaxInactiveInterval()一样的效果。
  • 设置一个特定会话的会话超时

  • cookie

    cookie实际上就是用户和服务器之间交换的一小段数据(一个名/值String对);
    服务器把cookie发送给客户,客户做出下一个请求时再把cookie返回给服务器。
    与cookie相关的方法封装在3个类中:HttpServletRequest、HttpServletResponse和Cookie。

  • cookie和首部

HttpSession对象的生命周期中的重要时刻:

注意,实现了HttpSessionBindingListener的属性类(如Dog类),不在DD中配置,因为它只与会话中的某个属性有关;

而HttpSessionListener和HttpSessionAttributeListener必须在DD中注册,因为它们会会话本身有关。

会话迁移【分布式Web应用的范畴】

分布式Web应用中,每次同一个客户做请求时,最后这个请求都有可能达到同一个servlet的不同实例;

即指向servlet A的请求A可能在一个VM中,而指向servlet A的请求B可能在另一个不同的VM中。
那么,ServletContext、ServletConfig和HttpSession对象如何表现?
答案:只有HttpSession对象(及其属性)会从一个VM中迁移到另一个VM中(即所有VM只有一个同样ID的HttpSession),其他对象复制(不同VM可能有多个这类对象)。

  • 属性迁移
    若属性是直接的Serializable对象,则该属性会自动在迁移时序列化,不用额外关心它。
    若属性类型不是Serializable呢?那么为了迁移,需要让属性对象类实现HttpSessionActivationListener,并使用激活/钝化回调方法解决这个问题。

Listener示例

  • 会话计数器

    这个监听者允许你跟踪这个Web应用中活动会话的个数:
    在DD中配置监听者:
    注意:

  • 属性监听者

    这个监听者,当每一次向会话增加属性、删除属性或者替换属性时,都能被跟踪到。
    在DD中配置监听者:

    注意,System.out标准输出在Tomcat中默认输出到tomcat/logs/catalina.log中。

  • 属性类(监听对它有影响的事件)

在DD中配置:

与会话相关的监听者

转载于:https://www.cnblogs.com/myitroad/p/6192523.html

你可能感兴趣的文章
python3-递归
查看>>
ubuntu解决 打开windows记事本.txt中文乱码的方法
查看>>
当代青年的三座大山
查看>>
requests接口测试——身份认证
查看>>
bzoj 3190: [JLOI2013]赛车
查看>>
作为程序员,你最常上的网站是什么
查看>>
oracle实现同时多表插入
查看>>
第四章-Python对象 课后答案
查看>>
yii2-user 一个好用的用户扩展
查看>>
POJ3274-Gold Balanced Lineup
查看>>
Visual Stuido 技巧(不断更新中……)
查看>>
An easy problem (位运算)
查看>>
Knight Moves (双向bfs)
查看>>
Elasticsearch学习之深入搜索一 --- 提高查询的精准度
查看>>
问题-FireDAC连接Sqlite3提示“unable to open database file”
查看>>
zookeeper集群搭建及Leader选举算法源码解析
查看>>
win7 wifi
查看>>
java gc的工作原理、如何优化GC的性能、如何和GC进行有效的交互
查看>>
今年剩余几个月的大概计划安排
查看>>
CSS3魔法堂:说说Multi-column Layout
查看>>