深入Session2
一、分布式环境Session的处理方法
分布式环境下要保持会话跟踪最简单的方式是只依靠客户端Cookie保存,不过大多数情况下还需要用到Session,一般的处理方式如下:
1、Session复制
每个web服务器有新session时都传递复制到其它的web服务器,所有的web服务器上都保留有所有的Session信息。此方法简单、能保证可靠性,但会增大网络带宽压力,如果session数量大,也会占用Web服务器资源。
2、Session绑定或粘性Session
用户初次访问某个web服务器产生session后,只在该web服务器中保存session,后面所有该用户的访问都定向到这台服务器上。此方法也简单,不会占用多余带宽和web服务器资源,但一旦某台web服务器故障,就会导致它上面的所有用户session数据丢失。
3、Session集中存储
所有Web服务器的session的数据统一保存在数据库、共享文件或分布式存储中,一般多是保存在分布式存储中,所有web服务器都集中存取Session。此方法可解决上面两种方法的缺点,但实现稍复杂,读写Session 数据引入了网络操作,这相对于本机的数据读取来说,存在时延和不稳定性,不过我们的通信基本都是发生在内网,问题不大。如果集中存储Session 的机器或者集群有问题,就会影响我们的应用。
二、Session实现基于Cookie或Url重写
第一次请求时web服务端会同时做url重写和Cookie写入SessionId操作(Java类服务器会如此处理),下次请求时会优先从Cookie中获取sesseionID,若存在后面请求就不会再做url重写。
我们都知道session的实现主要两种方式:cookie与url重写,而cookie是首选(默认)的方式,因为各种现代浏览器都默认开通cookie功能,但是每种浏览器也都有允许cookie失效的设置。
由于浏览器默认启动cookie功能,而且普通客户一般都不会取消cookie功能。久而久之,我们写代码的时候,也就不会在意session的具体实现,其实这里面还是有很多值得注意的地方,尤其在用户取消cookie功能的情况下。
一 servlet session实现与接口简要介绍:
servlet规范规定实现session的cookie名称强制为jsessionid(在servlet 3.0 可以自定义了),在浏览器第一次请求的时候,服务器产生一个唯一的id,并把这个id设置给一个名为jsessionid的cookie,然后再通过reponse的addcookie,输出到浏览器端。其实这些东西我们都可以通过debug模式下的去查看服务器,来验证这些内容;或者用http协议拦截器来查看,因为servlet的所有接口也都是基于http协议的
由于服务器没发现浏览器没提供任何cookie,服务器不知道是浏览器未提供cookie的原因:可能是cookie功能取消了,也可能是第一次访问。所以服务器生成一个名为jsessionid的cookie,用Set-Cookie来把cookie推给浏览器;并且,服务器的servlet在生成html页面的时候需要用reponse.encodeURL方法来编码url,该方法其实就是用来实现url重写功能的,这是因为浏览器可能是因为取消cookie功能,而未提供cookie的。服务器为了确保下次提交成功,必须确保生成给浏览器端的url带有jsessionid。
若cookie功能没取消,则浏览器浏览器第二次请求:
POST /cxt/login.do;jsessionid=3EF0AEC40F2C6C30A0580844C0E6B2E8 HTTP/1.1
Cookie: JSESSIONID=3EF0AEC40F2C6C30A0580844C0E6B2E8;
...
浏览器的下一次请求的时候用http的Cookie属性把当前domain的Cookie都推给服务器,来表明自己的身份。这次,服务器知道浏览器支持cookie功能,servlet不需要再使用reponse.encodeURL来编码url了
1.既然浏览器可能被取消cookie功能,那么我们输出给客户端的代码中必须要支持url重写功能,分几种情况解释
假如纯粹用jsp/servlet来写,那么我们必须手动用reponse.encodeURL来编码每一个url,包括<a>的href,form的action,或者其他href
2.使用其它web框架的话,最好消息使用框架提供的输出href功能,否则会有匪夷所思的结果。
比如用struts,若struts单独提供了一个tag来实现html:rewrite,比如<html:rewrite action='logout'/>,在没有jsessionid cookie的情况下,最后会生成http://localhost:8080/ctx/logout.do;jsessionid=0916FB057C169069;若有jsessionid cookie,则会生成http://localhost:8080/ctx/logout.do。但是我们还注意到html:rewrite还有一个href属性,假如我们用href属性的话,则struts不会生成带有jsessionid参数。
struts中提供url重写的功能的还有html:link与html:form,比如<html:link action="logout">logout</html:link>,这个tag功能与html:rewrite相似,也有href属性,生成带有<a>标签的html内容。<html:form action="/Login"></html:form>,html:form没有href属性,只有action属性。
3.假若没有使用任何框架,则可以使用jstl提供的url重写功能
jstl提供了标签来实现c:url,比如<c:url value="logout.do" />,这个也会根据浏览器是否支持cookie,来生成带有jsessionid属性的url。
相信通过上面的总结,是我们对怎么使用session与cookie有更深入的认识。记住,在用jsp/servlet实现系统的时候,尽量不要自己写<a>标签,最好使用系统框架自带的标签来实现,否则浏览器取消cookie功能的话,系统不支持url重写功能。
http://3237526.blog.51cto.com/3227526/1641971在Spring MVC当使用RedirectView或者"redirect:"前缀来做重定向时,Spring MVC最后会调用:
response.sendRedirect(response.encodeRedirectURL(url));对于IE来说,打开一个新的浏览器窗口,第一次访问服务器时,encodeRedirectURL()会在url后面附加上一段jsessionid,如果初始的url为"http://www.sina.com.cn",最终得到的url为"http://www.sina.com.cn;jsessionid=2jcligmgi6fh"。
这是典型的Java做事的方式,其他语言的服务器端平台并不会这样做。这个jsessionid很多时候会引起严重的问题,例如,如果你使用上述带有jsessionid的url直接访问新浪的网站,IE会向你报告:找不到服务器。
解决方法:
1. 不通过Spring MVC做重定向,自己直接调用:
response.sendRedirect(url);
return null; //告诉Spring MVC我已经完成了处理2. 修改Spring MVC的代码,将:
response.sendRedirect(response.encodeRedirectURL(url));
改为:
response.sendRedirect(url);3. encodeRedirectURL()仅在无法确定浏览器是否支持cookie的时候才会在url后面附加上jsessionid,如果它能找到一个jsessionid的cookie,它就认为浏览器是支持cookie的。因此可以自己创建一个jsessionid的cookie来欺骗encodeRedirectURL()。
Cookie cookie = new Cookie("jsessionid", "2jcligmgi6fh");
cookie.setMaxAge(Integer.MAX_VALUE);
response.addCookie(cookie);
然后再调用Spring MVC的重定向功能就没有问题了:
return new ModelAndView("redirect:"+url);
http://blog.csdn.net/tototuzuoquan/article/details/46971843response.encodeURL()和response.encodeRedirectURL()。
这2个方法会判断cookie是否可用,如果禁用了会解析出url中的jsessionid,并连接到指定的url后面,如果没有找到jessionid会自动帮我们生成一个。如果没禁用,则不做处理。
至于为什么要有2个方法?这2个方法有什么不同?google了一下,说是这2个方法在判断是否要包含jsessionid的逻辑上会稍有不同。
在调用HttpServletResponse.sendRedirect前,应该先调用encodeRedirectURL()方法,否则可能会丢失Sesssion信息。
这2个方法的使用方法如:response.sendRedirect(response.encodeURL("/myapp/input.jsp"));。
如果cookie没有禁用,我们在浏览器地址栏中看到的地址是这样的:/myapp/input.jsp,如果禁用了cookie,我们会看到:/myapp/input.jsp;jsessionid=73E6B2470C91A433A6698C7681FD44F4。
所以,我们在写web应用的时候,为了保险起见,应该在程序里的每一个跳转url上都使用这2个方法,来保证session的可用性。
http://www.cnblogs.com/huzi007/p/4137045.html
深入Session2的更多相关文章
- 项目总结笔记系列 Social Hub KT Session2
KT Session2: 主要是代码的实现(KT is knowledge Transfer) 如图所示,在整个Social Hub项目中,我们的项目Data Feed Service处于承上启下的作 ...
- 阿里巴巴笔试整理系列 Session2 中级篇
1知识点储备-----2笔试题总结-----3面试经验总结 知识点储备 2014年8月29日在线笔试题:20单选(40分钟内完成)+附加题(2道编程+1道问答) 1. 通过算法生成的随机数是“伪随机” ...
- 项目总结笔记系列 Maven Session2
主题:Maven插件 1.三个生命周期. 2.猛然间,一回首,竟然发现.之前的maven插件报错的原因,不是download的问题.是没有连接上网.在HP公司连接外网,用eclipse,是需要配置代理 ...
- 阿里巴巴笔试整理系列 Session2 高级篇
阿里一面:1. 入场就是红黑树,B数2. apache和nginx源码看过多少,平时看过什么技术论坛,还有没有看过更多的开源代码3. pthread 到自旋锁4. hadoop源码看过没5. 为什么选 ...
- Mysql事务探索及其在Django中的实践(一)
前言 很早就有想开始写博客的想法,一方面是对自己近期所学知识的一些总结.沉淀,方便以后对过去的知识进行梳理.追溯,一方面也希望能通过博客来认识更多相同技术圈的朋友.所幸近期通过了博客园的申请,那么今天 ...
- MySQL基础知识
一.MySQL安装 MySQL的下载 http://dev.mysql.com/downloads/mysql/ MySQL版本选择 MySQL功能自定义选择安装 1.功能自定义选择 2.路径自定义选 ...
- Struts2+Spring+Hibernate框架整合总结详细教程
一.SSH三大框架知识总结 Struts 2是Struts的下一代产品,是在 struts 1和WebWork的技术基础上进行了合并的全新的Struts 2框架.其全新的Struts 2的体系结构与S ...
- SQL Saturday 北京将于7月25日举办线下活动,欢迎参加
地点:北京微软(中国)有限公司[望京利星行],三层308室 报名地址:https://onedrive.live.com/redir?page=survey&resid=f ...
- 【分布式】Zookeeper使用--开源客户端
一.前言 上一篇博客已经介绍了如何使用Zookeeper提供的原生态Java API进行操作,本篇博文主要讲解如何通过开源客户端来进行操作. 二.ZkClient ZkClient是在Zookeepe ...
随机推荐
- linux使用代理进行apt安装 以 nord 为例
我的环境:(不必完全一样,只是提一下)----------- linux系统:kali 桌面:xface ----------------------------------------------- ...
- Centos 6.8安装ideaIU-2017.2.6-no-jdk
参考资料: (一)https://www.jetbrains.com/help/idea/2017.2/intellij-idea-help.pdf (链接: https://pan.baidu.c ...
- 从多个角度来理解协方差(covariance)
起源:协方差自然是由方差衍生而来的,方差反应的是一个变量(一维)的离散程度,到二维了,我们可以对每个维度求其离散程度,但我们还想知道更多.我们想知道两个维度(变量)之间的关系,直观的举例就是身高和体重 ...
- LeetCode--025--k个一组翻转链表(java)
给出一个链表,每 k 个节点一组进行翻转,并返回翻转后的链表. k 是一个正整数,它的值小于或等于链表的长度.如果节点总数不是 k 的整数倍,那么将最后剩余节点保持原有顺序. 示例 : 给定这个链表: ...
- Node.js简述
Node.js是2009年5月由Ryan Dahl 发布的服务器程序. 它封装了Google V8 JavaScript 引擎, 并将其重建为可在服务器上使用. 它旨在提供一种简单的构建可伸缩网络程序 ...
- python - 基础知识,if语句
一.认识计算机 计算机是一个高度集成的电子电路. 组成:CPU(中央处理器).内存 .主板 .电源(心脏) .显示器 .键盘 .鼠标 .显卡(NAVID,AMD) .硬盘 操作系统 :Windo ...
- canvas绘图基础
<canvas>元素是HTML5中的绘图元素,通过定义一个画布区域,然后使用javascript动态地在这个区域里面绘制图形,对于2D和3D图形都可以绘制,我们将其分成2D上下文和WebG ...
- IE9下table th不显示边框解决方法
添加下面两行样式即可 th, td{ background-clip: padding-box; /*背景被裁剪到内边距框*/ position:relative; }
- DOM获取元素的方法
DOM:document object module 文档对象模型 DOM就是描述整个html页面中节点关系的图谱,如下图. 1,通过ID,获取页面中元素的方法:(上下文必须是document) do ...
- powerdesigner(数据设计工具)
https://jingyan.baidu.com/album/4f7d57120468c91a2019279f.html?picindex=1 (摘抄 原网地址)