﻿<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:trackback="http://madskills.com/public/xml/rss/module/trackback/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/"><channel><title>BlogJava-cAng^Er-文章分类-|:Web Design:|</title><link>http://www.blogjava.net/xiaosao/category/19233.html</link><description>不懂我的人 , 离不了我 , 该了解了解我 !而懂我的人 , 更离不了我 , 因为他们爱我 。</description><language>zh-cn</language><lastBuildDate>Sat, 20 Oct 2007 17:34:49 GMT</lastBuildDate><pubDate>Sat, 20 Oct 2007 17:34:49 GMT</pubDate><ttl>60</ttl><item><title>&lt;转&gt;AJAX技术介绍(什么是AJAX?)</title><link>http://www.blogjava.net/xiaosao/articles/153649.html</link><dc:creator>cAng^Er</dc:creator><author>cAng^Er</author><pubDate>Wed, 17 Oct 2007 10:55:00 GMT</pubDate><guid>http://www.blogjava.net/xiaosao/articles/153649.html</guid><wfw:comment>http://www.blogjava.net/xiaosao/comments/153649.html</wfw:comment><comments>http://www.blogjava.net/xiaosao/articles/153649.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/xiaosao/comments/commentRss/153649.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/xiaosao/services/trackbacks/153649.html</trackback:ping><description><![CDATA[<p>经常听说AJAX 但是一直不清楚它是什么东西也没去弄~ 今天突然想好好的了解一下~<br />
&nbsp; 看到个文章 转到这里~<br />
&nbsp; 原文地址:<a href="http://www.iamwinter.com/article.asp?id=238">http://www.iamwinter.com/article.asp?id=238</a><br />
&nbsp;&nbsp;<br />
&nbsp;一、AJAX开发者的最新工具和技术<br />
<br />
　　基于XML的异步JavaScript，简称AJAX，是当前Web创新（称为Web2.0）中的一个王冠。感谢组成AJAX的各种技术，Web应用的交互如Flickr,&nbsp;Backpack和<a href="http://www.google.com/" target="_blank">Google</a>在这方面已经有质的飞跃。这个术语源自描述从基于网页的Web应用到基于数据的应用的转换。在基于数据的应用中，用户需求的数据如联系人列表，可以从独立于实际网页的服务端取得并且可以被动态地写入网页中，给缓慢的Web应用体验着色使之像桌面应用一样。<br />
<br />
　　虽然大部分开发人员在过去使用过XMLHttp或者使用Iframe来加载数据，但仅到现在我们才看到传统的开发人员和公司开始采用这些技术。就像新的编程语言或模型伴随着更多的痛苦，开发人员需要学习新的技巧及如何最好利用这些新技术。<br />
<br />
　　二、AJAX模式<br />
<br />
　　许多重要的技术和AJAX开发模式可以从现有的知识中获取。例如，在一个发送请求到服务端的应用中，必须包含请求顺序、优先级、超时响应、错误处理及回调，其中许多元素已经在Web服务中包含了，就像现在的SOA。AJAX开发人员拥有一个完整的系统架构知识。同时，随着技术的成熟还会有许多地方需要改进，特别是UI部分的易用性。<br />
<br />
　　AJAX开发与传统的CS开发有很大的不同。这些不同引入了新的编程问题，最大的问题在于易用性。由于AJAX依赖浏览器的JavaScript和XML，浏览器的兼容性和支持的标准也变得和JavaScript的运行时性能一样重要了。这些问题中的大部分来源于浏览器、服务器和技术的组合，因此必须理解如何才能最好的使用这些技术。<br />
<br />
　　综合各种变化的技术和强耦合的客户服务端环境，AJAX提出了一种新的开发方式。AJAX开发人员必须理解传统的MVC架构，这限制了应用层次之间的边界。同时，开发人员还需要考虑CS环境的外部和使用AJAX技术来重定型MVC边界。最重要的是，AJAX开发人员必须禁止以页面集合的方式来考虑Web应用而需要将其认为是单个页面。一旦UI设计与服务架构之间的范围被严格区分开来后，开发人员就需要更新和变化的技术集合了。<br />
<br />
　　三、时刻想着用户<br />
<br />
　　AJAX的最大机遇在于用户体验。在使应用更快响应和创新的过程中，定义Web应用的规则正在被重写；因此开发人员必须更注重用户。现在用户已经逐渐习惯如何使用Web应用了。例如用户通常希望每一次按钮点击会导致几秒的延迟和屏幕刷新，但AJAX正在打破这种长时间的状况。因此用户需要重新体验按钮点击的响应了。<br />
<br />
　　可用性是AJAX另人激动的地方而且已经产生了几种新颖的技术。其中最引人注目的是一种称为&#8220;黄色隐出&#8221;的技术，他在数据更新之前时将用户界面变为黄色，更新完成后立刻恢复原来的颜色。AJAX开发人员将用户从Web应用的负载中解放出来；小心地利用AJAX提供的丰富接口，不久桌面开发人员会发现AJAX是他们的方向。<br />
<br />
　　四、几种工具和技术<br />
<br />
　　随着AJAX迅速地引人注目起来，我想开发人员对这种技术的期待也迅速地增加。就像任何新技术，AJAX的兴旺也需要一整个开发工具/编程语言及相关技术系统来支撑。<br />
<br />
　　１、JavaScript<br />
<br />
　　如名字所示AJAX的概念中最重要而最被忽视的是他也是一种JavaScript编程语言。JavaScript是一种粘合剂使AJAX应用的各部分集成在一起。在大部分时间，JavaScript通常被服务端开发人员认为是一种企业级应用不需要使用的东西应该尽力避免。这种观点来来自以前编写JavaScript代码的经历：繁杂而又易出错的语言。类似的，他也被认为将应用逻辑任意地散布在服务端和客户端中，这使得问题很难被发现而且代码很难重用。在AJAX中JavaScript主要被用来传递用户界面上的数据到服务端并返回结果。XMLHttpRequest对象用来响应通过HTTP传递的数据，一旦数据返回到客户端就可以立刻使用DOM将数据放到网面上。<br />
<br />
　　２、XMLHttpRequest<br />
<br />
　　XMLHttpRequest对象在大部分浏览器上已经实现而且拥有一个简单的接口允许数据从客户端传递到服务端，但并不会打断用户当前的操作。使用XMLHttpRequest传送的数据可以是任何格式，虽然从名字上建议是XML格式的数据。<br />
<br />
　　开发人员应该已经熟悉了许多其他XML相关的技术。XPath可以访问XML文档中的数据，但理解XML&nbsp;DOM是必须的。类似的，XSLT是最简单而快速的从XML数据生成HTML或XML的方式。许多开发人员已经熟悉Xpath和XSLT，因此AJAX选择XML作为数据交换格式有意义的。XSLT可以被用在客户端和服务端，他能够减少大量的用JavaScript编写的应用逻辑。<br />
<br />
　　３、CSS<br />
<br />
　　为了正确的浏览AJAX应用，CSS是一种AJAX开发人员所需要的重要武器。CSS提供了从内容中分离应用样式和设计的机制。虽然CSS在AJAX应用中扮演至关重要的角色，但他也是构建创建跨浏览器应用的一大阻碍，因为不同的浏览器厂商支持各种不同的CSS级别。<br />
<br />
　　五、服务器端<br />
<br />
　　但不像在客户端，在服务端AJAX应用还是使用建立在如Java,.Net和PHP语言基础上机制；并没有改变这个领域中的主要方式。<br />
<br />
　　既然如此，我们对Ruby&nbsp;on&nbsp;Rails框架的兴趣也就迅速增加了。在一年多前，Ruby&nbsp;on&nbsp;Rails已经吸引了大量开发人员基于其强大功能来构建Web和AJAX应用。虽然目前还有很多快速应用开发工具存在，Ruby&nbsp;on&nbsp;Rails看起来已经储备了简化构建AJAX应用的能力。<br />
<br />
　　六、开发工具<br />
<br />
　　在实际构建AJAX应用中，你需要的不只是文本编辑器。既然是JavaScript非编译的，他可以容易地编写和运行在浏览器中；然而，许多工具提供了有用的扩展如语法高亮和智能完成。<br />
<br />
　　不同的IDE提供了对JavaScript支持的不同等级。来自JetBrains的IntelliJ&nbsp;IDEA是一个用来JavaScript开发的更好的IDE，虽然许多开发人员也喜欢Microsoft&#8217;s&nbsp;Visual&nbsp;Studio产品（允诺会在最新的版本中改善对AJAX的支持）。Eclipse包含了两个免费的JavaScript编辑器插件和一个商业的来自ActiveStat的Komodo&nbsp;IDE。<br />
<br />
　　另一个JavaScript和AJAX开发中的问题是调试困难。不同的浏览器提供不同的通常是隐藏的运行时错误信息，而JavaScript的缺陷如双重变量赋值（通常是由于缺少数据类型）使得调试更加困难。在AJAX的开发中，调试就更复杂了，因为其需要标识究竟是客户端还是服务端产生的错误。在过去，JavaScript调试的方法是删除所有代码然后一行行的增加直到错误出现。现在，更多开发人员回到为IE准备的Microsoft&nbsp;Script&nbsp;Debugger和为Mozilla浏览器准备的Venkman。<br />
<br />
　　七、浏览器兼容性<br />
<br />
　　JavaScript编程的最大问题来自不同的浏览器对各种技术和标准的支持。构建一个运行在不同浏览器（如IE和火狐）是一个困难的任务。因此几种AJAX&nbsp;JavaScript框架或者生成基于服务端逻辑或标记库的JavaScript，或者提供符合跨浏览器AJAX开发的客户端JavaScript库。一些流行的框架包括：AJAX.Net,&nbsp;Backbase,&nbsp;Bitkraft,&nbsp;Django,&nbsp;DOJO,&nbsp;DWR,&nbsp;MochiKit,&nbsp;Prototype,&nbsp;Rico,&nbsp;Sajax,&nbsp;Sarissa,&nbsp;and&nbsp;Script.aculo.us.&nbsp;<br />
<br />
　　这些框架给开发人员更多的空间使得他们不需要担心跨浏览器的问题。虽然这些框架提升了开发人员构建应用的能力，但由于厂商已经开发了更细节的用户界面的打包组件解决方案，因此在AJAX组件市场中需要考虑一些其他因素。例如提供通用用户界面的组件如组合框和数据栅格的几个厂商，都可以被用来在应用中创建良好的通过类似电子数据表方式来查看和编辑数据的体验。但这些组件不仅是封装了组件的用户界面而且包括与服务端数据的通讯方式，这些组件通常使用基于标记方式来实现如ASP.Net或JSF控件。<br />
<br />
　　八、展望<br />
<br />
　　最近IE和火狐之间的浏览器之争变得火热起来，因此AJAX开发人员需要足够敏捷的作出反应。关键点在一些问题如CSS或XML，虽然各种浏览器形成采用最新标准的不同阵营（如Mozilla拥抱SVG和E4X标准及在最新火狐BETA版本中使用XUL，而<a href="http://www.microsoft.com/china" target="_blank">微软</a>使用自己的XAML技术）。所有这些技术代表当前AJAX主流JavaScript和XML的市场方向改变。<br />
<br />
　　总的来说，AJAX开发人员必须尽快地跟进最新的技术并利用高产的工具集。成功的AJAX开发人员还需要留心他们的使用者以避免将任何问题扩大化。并且AJAX开发人员还需要持续地创新来创建增强Web应用易用性的新方法。 <br />
</p>
<img src ="http://www.blogjava.net/xiaosao/aggbug/153649.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/xiaosao/" target="_blank">cAng^Er</a> 2007-10-17 18:55 <a href="http://www.blogjava.net/xiaosao/articles/153649.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>  Session详解 </title><link>http://www.blogjava.net/xiaosao/articles/93898.html</link><dc:creator>cAng^Er</dc:creator><author>cAng^Er</author><pubDate>Mon, 15 Jan 2007 03:28:00 GMT</pubDate><guid>http://www.blogjava.net/xiaosao/articles/93898.html</guid><wfw:comment>http://www.blogjava.net/xiaosao/comments/93898.html</wfw:comment><comments>http://www.blogjava.net/xiaosao/articles/93898.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/xiaosao/comments/commentRss/93898.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/xiaosao/services/trackbacks/93898.html</trackback:ping><description><![CDATA[
		<strong>原文地址：<a href="http://stieglitzcc.spaces.live.com/Blog/cns!6A816552E3F0D074!148.entry">http://stieglitzcc.spaces.live.com/Blog/cns!6A816552E3F0D074!148.entry</a><br />Session详解</strong>
		<hr color="#999999" noshade="" size="1" />
		<p align="left">
		</p>
		<p>摘要：虽然session机制在web应用程序中被采用已经很长时间了，但是仍然有很多人不清楚session机制的本质，以至不能正确的应用这一技术。本文将详细讨论session的工作机制并且对在Java web application中应用session机制时常见的问题作出解答。</p>
		<br />
		<p>目录：<br />一、术语session<br />二、HTTP协议与状态保持<br />三、理解cookie机制<br />四、理解session机制<br />五、理解javax.servlet.http.HttpSession<br />六、HttpSession常见问题<br />七、跨应用程序的session共享<br />八、总结<br />参考文档</p>
		<br />
		<p>
				<strong>一、术语session</strong>
				<br />在我的经验里，session这个词被滥用的程度大概仅次于transaction，更加有趣的是transaction与session在某些语境下的含义是相同的。</p>
		<br />
		<p>session，中文经常翻译为会话，其本来的含义是指有始有终的一系列动作/消息，比如打电话时从拿起电话拨号到挂断电话这中间的一系列过程可以称之为一个session。有时候我们可以看到这样的话“在一个浏览器会话期间，...”，这里的会话一词用的就是其本义，是指从一个浏览器窗口打开到关闭这个期间①。最混乱的是“用户（客户端）在一次会话期间”这样一句话，它可能指用户的一系列动作（一般情况下是同某个具体目的相关的一系列动作，比如从登录到选购商品到结账登出这样一个网上购物的过程，有时候也被称为一个transaction），然而有时候也可能仅仅是指一次连接，也有可能是指含义①，其中的差别只能靠上下文来推断②。</p>
		<br />
		<p>然而当session一词与网络协议相关联时，它又往往隐含了“面向连接”和/或“保持状态”这样两个含义，“面向连接”指的是在通信双方在通信之前要先建立一个通信的渠道，比如打电话，直到对方接了电话通信才能开始，与此相对的是写信，在你把信发出去的时候你并不能确认对方的地址是否正确，通信渠道不一定能建立，但对发信人来说，通信已经开始了。“保持状态”则是指通信的一方能够把一系列的消息关联起来，使得消息之间可以互相依赖，比如一个服务员能够认出再次光临的老顾客并且记得上次这个顾客还欠店里一块钱。这一类的例子有“一个TCP session”或者“一个POP3 session”③。</p>
		<br />
		<p>而到了web服务器蓬勃发展的时代，session在web开发语境下的语义又有了新的扩展，它的含义是指一类用来在客户端与服务器之间保持状态的解决方案④。有时候session也用来指这种解决方案的存储结构，如“把xxx保存在session里”⑤。由于各种用于web开发的语言在一定程度上都提供了对这种解决方案的支持，所以在某种特定语言的语境下，session也被用来指代该语言的解决方案，比如经常把Java里提供的 javax.servlet.http.HttpSession简称为session⑥。</p>
		<br />
		<p>鉴于这种混乱已不可改变，本文中session一词的运用也会根据上下文有不同的含义，请大家注意分辨。<br />在本文中，使用中文“浏览器会话期间”来表达含义①，使用“session机制”来表达含义④，使用“session”表达含义⑤，使用具体的“HttpSession”来表达含义⑥</p>
		<br />
		<p>
				<strong>二、HTTP协议与状态保持</strong>
				<br />HTTP协议本身是无状态的，这与HTTP协议本来的目的是相符的，客户端只需要简单的向服务器请求下载某些文件，无论是客户端还是服务器都没有必要纪录彼此过去的行为，每一次请求之间都是独立的，好比一个顾客和一个自动售货机或者一个普通的（非会员制）大卖场之间的关系一样。</p>
		<br />
		<p>然而聪明（或者贪心？）的人们很快发现如果能够提供一些按需生成的动态信息会使web变得更加有用，就像给有线电视加上点播功能一样。这种需求一方面迫使HTML逐步添加了表单、脚本、DOM等客户端行为，另一方面在服务器端则出现了CGI规范以响应客户端的动态请求，作为传输载体的 HTTP协议也添加了文件上载、cookie这些特性。其中cookie的作用就是为了解决HTTP协议无状态的缺陷所作出的努力。至于后来出现的 session机制则是又一种在客户端与服务器之间保持状态的解决方案。</p>
		<br />
		<p>让我们用几个例子来描述一下cookie和session机制之间的区别与联系。笔者曾经常去的一家咖啡店有喝5杯咖啡免费赠一杯咖啡的优惠，然而一次性消费5杯咖啡的机会微乎其微，这时就需要某种方式来纪录某位顾客的消费数量。想象一下其实也无外乎下面的几种方案：<br />1、该店的店员很厉害，能记住每位顾客的消费数量，只要顾客一走进咖啡店，店员就知道该怎么对待了。这种做法就是协议本身支持状态。<br />2、发给顾客一张卡片，上面记录着消费的数量，一般还有个有效期限。每次消费时，如果顾客出示这张卡片，则此次消费就会与以前或以后的消费相联系起来。这种做法就是在客户端保持状态。<br />3、发给顾客一张会员卡，除了卡号之外什么信息也不纪录，每次消费时，如果顾客出示该卡片，则店员在店里的纪录本上找到这个卡号对应的纪录添加一些消费信息。这种做法就是在服务器端保持状态。</p>
		<br />
		<p>由于HTTP协议是无状态的，而出于种种考虑也不希望使之成为有状态的，因此，后面两种方案就成为现实的选择。具体来说cookie机制采用的是在客户端保持状态的方案，而session机制采用的是在服务器端保持状态的方案。同时我们也看到，由于采用服务器端保持状态的方案在客户端也需要保存一个标识，所以session机制可能需要借助于cookie机制来达到保存标识的目的，但实际上它还有其他选择。</p>
		<br />
		<p>
				<strong>三、理解cookie机制</strong>
				<br />cookie机制的基本原理就如上面的例子一样简单，但是还有几个问题需要解决：“会员卡”如何分发；“会员卡”的内容；以及客户如何使用“会员卡”。</p>
		<br />
		<p>正统的cookie分发是通过扩展HTTP协议来实现的，服务器通过在HTTP的响应头中加上一行特殊的指示以提示浏览器按照指示生成相应的cookie。然而纯粹的客户端脚本如JavaScript或者VBScript也可以生成cookie。</p>
		<br />
		<p>而cookie的使用是由浏览器按照一定的原则在后台自动发送给服务器的。浏览器检查所有存储的cookie，如果某个cookie所声明的作用范围大于等于将要请求的资源所在的位置，则把该cookie附在请求资源的HTTP请求头上发送给服务器。意思是麦当劳的会员卡只能在麦当劳的店里出示，如果某家分店还发行了自己的会员卡，那么进这家店的时候除了要出示麦当劳的会员卡，还要出示这家店的会员卡。</p>
		<br />
		<p>cookie的内容主要包括：名字，值，过期时间，路径和域。<br />其中域可以指定某一个域比如.google.com，相当于总店招牌，比如宝洁公司，也可以指定一个域下的具体某台机器比如www.google.com或者froogle.google.com，可以用飘柔来做比。<br />路径就是跟在域名后面的URL路径，比如/或者/foo等等，可以用某飘柔专柜做比。<br />路径与域合在一起就构成了cookie的作用范围。<br />如果不设置过期时间，则表示这个cookie的生命期为浏览器会话期间，只要关闭浏览器窗口，cookie就消失了。这种生命期为浏览器会话期的 cookie被称为会话cookie。会话cookie一般不存储在硬盘上而是保存在内存里，当然这种行为并不是规范规定的。如果设置了过期时间，浏览器就会把cookie保存到硬盘上，关闭后再次打开浏览器，这些cookie仍然有效直到超过设定的过期时间。</p>
		<br />
		<p>存储在硬盘上的cookie可以在不同的浏览器进程间共享，比如两个IE窗口。而对于保存在内存里的cookie，不同的浏览器有不同的处理方式。对于IE，在一个打开的窗口上按Ctrl-N（或者从文件菜单）打开的窗口可以与原窗口共享，而使用其他方式新开的IE进程则不能共享已经打开的窗口的内存cookie；对于Mozilla Firefox0.8，所有的进程和标签页都可以共享同样的cookie。一般来说是用javascript的window.open打开的窗口会与原窗口共享内存cookie。浏览器对于会话cookie的这种只认cookie不认人的处理方式经常给采用session机制的web应用程序开发者造成很大的困扰。</p>
		<br />
		<p>下面就是一个goolge设置cookie的响应头的例子<br />HTTP/1.1 302 Found<br />Location:<a href="http://www.google.com/intl/zh-CN/"><u><font color="#800080"> http://www.google.com/intl/zh-CN/</font></u></a><br />Set-Cookie: PREF=ID=0565f77e132de138:NW=1:TM=1098082649:LM=1098082649:S=KaeaCFPo49RiA_d8; expires=Sun, 17-Jan-2038 19:14:07 GMT; path=/; domain=.google.com<br />Content-Type: text/html</p>
		<br />
		<p align="center">
				<img height="293" src="http://dev2dev.bea.com.cn/images/paihang_article/041020/image002.jpg" width="408" />
		</p>
		<br />
		<p>
				<br />这是使用HTTPLook这个HTTP Sniffer软件来俘获的HTTP通讯纪录的一部分</p>
		<br />
		<p align="center">
				<img height="344" src="http://dev2dev.bea.com.cn/images/paihang_article/041020/image004.jpg" width="432" />
		</p>
		<br />
		<p>
				<br />浏览器在再次访问goolge的资源时自动向外发送cookie</p>
		<br />
		<p align="center">
				<img height="305" src="http://dev2dev.bea.com.cn/images/paihang_article/041020/image006.jpg" width="421" />
		</p>
		<br />
		<p>
				<br />使用Firefox可以很容易的观察现有的cookie的值<br />使用HTTPLook配合Firefox可以很容易的理解cookie的工作原理。</p>
		<br />
		<p align="center">
				<img height="248" src="http://dev2dev.bea.com.cn/images/paihang_article/041020/image008.jpg" width="324" />
		</p>
		<br />
		<p>
				<br />IE也可以设置在接受cookie前询问</p>
		<br />
		<p align="center">
				<img height="249" src="http://dev2dev.bea.com.cn/images/paihang_article/041020/image010.jpg" width="239" />
		</p>
		<br />
		<p>
				<br />这是一个询问接受cookie的对话框。</p>
		<br />
		<p>
				<strong>四、理解session机制</strong>
				<br />session机制是一种服务器端的机制，服务器使用一种类似于散列表的结构（也可能就是使用散列表）来保存信息。</p>
		<br />
		<p>当程序需要为某个客户端的请求创建一个session的时候，服务器首先检查这个客户端的请求里是否已包含了一个session标识 - 称为session id，如果已包含一个session id则说明以前已经为此客户端创建过session，服务器就按照session id把这个session检索出来使用（如果检索不到，可能会新建一个），如果客户端请求不包含session id，则为此客户端创建一个session并且生成一个与此session相关联的session id，session id的值应该是一个既不会重复，又不容易被找到规律以仿造的字符串，这个session id将被在本次响应中返回给客户端保存。</p>
		<br />
		<p>保存这个session id的方式可以采用cookie，这样在交互过程中浏览器可以自动的按照规则把这个标识发挥给服务器。一般这个cookie的名字都是类似于 SEEESIONID，而。比如weblogic对于web应用程序生成的cookie，JSESSIONID= ByOK3vjFD75aPnrF7C2HmdnV6QZcEbzWoWiBYEnLerjQ99zWpBng!-145788764，它的名字就是 JSESSIONID。</p>
		<br />
		<p>由于cookie可以被人为的禁止，必须有其他机制以便在cookie被禁止时仍然能够把session id传递回服务器。经常被使用的一种技术叫做URL重写，就是把session id直接附加在URL路径的后面，附加方式也有两种，一种是作为URL路径的附加信息，表现形式为http://...../xxx; jsessionid=ByOK3vjFD75aPnrF7C2HmdnV6QZcEbzWoWiBYEnLerjQ99zWpBng!-145788764<br />另一种是作为查询字符串附加在URL后面，表现形式为http://...../xxx?jsessionid=ByOK3vjFD75aPnrF7C2HmdnV6QZcEbzWoWiBYEnLerjQ99zWpBng!-145788764<br />这两种方式对于用户来说是没有区别的，只是服务器在解析的时候处理的方式不同，采用第一种方式也有利于把session id的信息和正常程序参数区分开来。<br />为了在整个交互过程中始终保持状态，就必须在每个客户端可能请求的路径后面都包含这个session id。</p>
		<br />
		<p>另一种技术叫做表单隐藏字段。就是服务器会自动修改表单，添加一个隐藏字段，以便在表单提交时能够把session id传递回服务器。比如下面的表单<br />&lt;form name="testform" action="/xxx"&gt;<br />&lt;input type="text"&gt;<br />&lt;/form&gt;<br />在被传递给客户端之前将被改写成<br />&lt;form name="testform" action="/xxx"&gt;<br />&lt;input type="hidden" name="jsessionid" value="ByOK3vjFD75aPnrF7C2HmdnV6QZcEbzWoWiBYEnLerjQ99zWpBng!-145788764"&gt;<br />&lt;input type="text"&gt;<br />&lt;/form&gt;<br />这种技术现在已较少应用，笔者接触过的很古老的iPlanet6(SunONE应用服务器的前身)就使用了这种技术。<br />实际上这种技术可以简单的用对action应用URL重写来代替。</p>
		<br />
		<p>在谈论session机制的时候，常常听到这样一种误解“只要关闭浏览器，session就消失了”。其实可以想象一下会员卡的例子，除非顾客主动对店家提出销卡，否则店家绝对不会轻易删除顾客的资料。对session来说也是一样的，除非程序通知服务器删除一个session，否则服务器会一直保留，程序一般都是在用户做log off的时候发个指令去删除session。然而浏览器从来不会主动在关闭之前通知服务器它将要关闭，因此服务器根本不会有机会知道浏览器已经关闭，之所以会有这种错觉，是大部分session机制都使用会话cookie来保存session id，而关闭浏览器后这个session id就消失了，再次连接服务器时也就无法找到原来的session。如果服务器设置的cookie被保存到硬盘上，或者使用某种手段改写浏览器发出的 HTTP请求头，把原来的session id发送给服务器，则再次打开浏览器仍然能够找到原来的session。</p>
		<br />
		<p>恰恰是由于关闭浏览器不会导致session被删除，迫使服务器为seesion设置了一个失效时间，当距离客户端上一次使用session的时间超过这个失效时间时，服务器就可以认为客户端已经停止了活动，才会把session删除以节省存储空间。</p>
		<br />
		<p>
				<strong>五、理解javax.servlet.http.HttpSession</strong>
				<br />HttpSession是Java平台对session机制的实现规范，因为它仅仅是个接口，具体到每个web应用服务器的提供商，除了对规范支持之外，仍然会有一些规范里没有规定的细微差异。这里我们以BEA的Weblogic Server8.1作为例子来演示。</p>
		<br />
		<p>首先，Weblogic Server提供了一系列的参数来控制它的HttpSession的实现，包括使用cookie的开关选项，使用URL重写的开关选项，session持久化的设置，session失效时间的设置，以及针对cookie的各种设置，比如设置cookie的名字、路径、域，cookie的生存时间等。</p>
		<br />
		<p>一般情况下，session都是存储在内存里，当服务器进程被停止或者重启的时候，内存里的session也会被清空，如果设置了 session的持久化特性，服务器就会把session保存到硬盘上，当服务器进程重新启动或这些信息将能够被再次使用，Weblogic Server支持的持久性方式包括文件、数据库、客户端cookie保存和复制。</p>
		<br />
		<p>复制严格说来不算持久化保存，因为session实际上还是保存在内存里，不过同样的信息被复制到各个cluster内的服务器进程中，这样即使某个服务器进程停止工作也仍然可以从其他进程中取得session。</p>
		<br />
		<p>cookie生存时间的设置则会影响浏览器生成的cookie是否是一个会话cookie。默认是使用会话cookie。有兴趣的可以用它来试验我们在第四节里提到的那个误解。</p>
		<br />
		<p>cookie的路径对于web应用程序来说是一个非常重要的选项，Weblogic Server对这个选项的默认处理方式使得它与其他服务器有明显的区别。后面我们会专题讨论。</p>
		<br />
		<p>关于session的设置参考[5]<a href="http://e-docs.bea.com/wls/docs70/webapp/weblogic_xml.html"><u><font color="#0000ff"> http://e-docs.bea.com/wls/docs70/webapp/weblogic_xml.html</font></u></a>#1036869</p>
		<br />
		<p>
				<strong>六、HttpSession常见问题</strong>
				<br />（在本小节中session的含义为⑤和⑥的混合）</p>
		<br />
		<p>
				<br />1、session在何时被创建<br />一个常见的误解是以为session在有客户端访问时就被创建，然而事实是直到某 server端程序调用HttpServletRequest.getSession(true)这样的语句时才被创建，注意如果JSP没有显示的使用 &lt;%@page session="false"%&gt; 关闭session，则JSP文件在编译成Servlet时将会自动加上这样一条语句HttpSession session = HttpServletRequest.getSession(true);这也是JSP中隐含的session对象的来历。</p>
		<br />
		<p>由于session会消耗内存资源，因此，如果不打算使用session，应该在所有的JSP中关闭它。</p>
		<br />
		<p>2、session何时被删除<br />综合前面的讨论，session在下列情况下被删除a.程序调用HttpSession.invalidate();或b.距离上一次收到客户端发送的session id时间间隔超过了session的超时设置;或c.服务器进程被停止（非持久session）</p>
		<br />
		<p>3、如何做到在浏览器关闭时删除session<br />严格的讲，做不到这一点。可以做一点努力的办法是在所有的客户端页面里使用javascript代码window.oncolose来监视浏览器的关闭动作，然后向服务器发送一个请求来删除session。但是对于浏览器崩溃或者强行杀死进程这些非常规手段仍然无能为力。</p>
		<br />
		<p>4、有个HttpSessionListener是怎么回事<br />你可以创建这样的listener去监控session的创建和销毁事件，使得在发生这样的事件时你可以做一些相应的工作。注意是session的创建和销毁动作触发listener，而不是相反。类似的与 HttpSession有关的listener还有HttpSessionBindingListener， HttpSessionActivationListener和HttpSessionAttributeListener。</p>
		<br />
		<p>5、存放在session中的对象必须是可序列化的吗<br />不是必需的。要求对象可序列化只是为了session能够在集群中被复制或者能够持久保存或者在必要时server能够暂时把session交换出内存。在Weblogic Server的session中放置一个不可序列化的对象在控制台上会收到一个警告。我所用过的某个iPlanet版本如果session中有不可序列化的对象，在session销毁时会有一个Exception，很奇怪。</p>
		<br />
		<p>6、如何才能正确的应付客户端禁止cookie的可能性<br />对所有的URL使用URL重写，包括超链接，form的action，和重定向的URL，具体做法参见[6]<br />http://e-docs.bea.com/wls/docs70/webapp/sessions.html#100770</p>
		<br />
		<p>7、开两个浏览器窗口访问应用程序会使用同一个session还是不同的session<br />参见第三小节对cookie的讨论，对session来说是只认id不认人，因此不同的浏览器，不同的窗口打开方式以及不同的cookie存储方式都会对这个问题的答案有影响。</p>
		<br />
		<p>8、如何防止用户打开两个浏览器窗口操作导致的session混乱<br />这个问题与防止表单多次提交是类似的，可以通过设置客户端的令牌来解决。就是在服务器每次生成一个不同的id返回给客户端，同时保存在session里，客户端提交表单时必须把这个id也返回服务器，程序首先比较返回的id与保存在session里的值是否一致，如果不一致则说明本次操作已经被提交过了。可以参看《J2EE核心模式》关于表示层模式的部分。需要注意的是对于使用javascript window.open打开的窗口，一般不设置这个id，或者使用单独的id，以防主窗口无法操作，建议不要再window.open打开的窗口里做修改操作，这样就可以不用设置。</p>
		<br />
		<p>9、为什么在Weblogic Server中改变session的值后要重新调用一次session.setValue<br />做这个动作主要是为了在集群环境中提示Weblogic Server session中的值发生了改变，需要向其他服务器进程复制新的session值。</p>
		<br />
		<p>10、为什么session不见了<br />排除session正常失效的因素之外，服务器本身的可能性应该是微乎其微的，虽然笔者在 iPlanet6SP1加若干补丁的Solaris版本上倒也遇到过；浏览器插件的可能性次之，笔者也遇到过3721插件造成的问题；理论上防火墙或者代理服务器在cookie处理上也有可能会出现问题。<br />出现这一问题的大部分原因都是程序的错误，最常见的就是在一个应用程序中去访问另外一个应用程序。我们在下一节讨论这个问题。</p>
		<br />
		<p>七、跨应用程序的session共享<br /><br />常常有这样的情况，一个大项目被分割成若干小项目开发，为了能够互不干扰，要求每个小项目作为一个单独的web应用程序开发，可是到了最后突然发现某几个小项目之间需要共享一些信息，或者想使用session来实现SSO (single sign on)，在session中保存login的用户信息，最自然的要求是应用程序间能够访问彼此的session。</p>
		<br />
		<p>然而按照Servlet规范，session的作用范围应该仅仅限于当前应用程序下，不同的应用程序之间是不能够互相访问对方的 session的。各个应用服务器从实际效果上都遵守了这一规范，但是实现的细节却可能各有不同，因此解决跨应用程序session共享的方法也各不相同。</p>
		<br />
		<p>首先来看一下Tomcat是如何实现web应用程序之间session的隔离的，从Tomcat设置的cookie路径来看，它对不同的应用程序设置的cookie路径是不同的，这样不同的应用程序所用的session id是不同的，因此即使在同一个浏览器窗口里访问不同的应用程序，发送给服务器的session id也可以是不同的。<br /></p>
		<br />
		<p align="center">
				<img height="219" src="http://dev2dev.bea.com.cn/images/paihang_article/041020/image012.jpg" width="288" />
				<img height="215" src="http://dev2dev.bea.com.cn/images/paihang_article/041020/image014.jpg" width="257" />
		</p>
		<br />
		<p>根据这个特性，我们可以推测Tomcat中session的内存结构大致如下。<br /></p>
		<br />
		<p align="center">
				<img height="278" src="http://dev2dev.bea.com.cn/images/paihang_article/041020/image016.jpg" width="444" />
		</p>
		<br />
		<p>笔者以前用过的iPlanet也采用的是同样的方式，估计SunONE与iPlanet之间不会有太大的差别。对于这种方式的服务器，解决的思路很简单，实际实行起来也不难。要么让所有的应用程序共享一个session id，要么让应用程序能够获得其他应用程序的session id。</p>
		<br />
		<p>iPlanet中有一种很简单的方法来实现共享一个session id，那就是把各个应用程序的cookie路径都设为/（实际上应该是/NASApp，对于应用程序来讲它的作用相当于根）。<br />&lt;session-info&gt;<br />&lt;path&gt;/NASApp&lt;/path&gt;<br />&lt;/session-info&gt;</p>
		<br />
		<p>需要注意的是，操作共享的session应该遵循一些编程约定，比如在session attribute名字的前面加上应用程序的前缀，使得setAttribute("name", "neo")变成setAttribute("app1.name", "neo")，以防止命名空间冲突，导致互相覆盖。</p>
		<br />
		<p>
				<br />在Tomcat中则没有这么方便的选择。在Tomcat版本3上，我们还可以有一些手段来共享session。对于版本4以上的 Tomcat，目前笔者尚未发现简单的办法。只能借助于第三方的力量，比如使用文件、数据库、JMS或者客户端cookie，URL参数或者隐藏字段等手段。</p>
		<br />
		<p>我们再看一下Weblogic Server是如何处理session的。<br /></p>
		<br />
		<p align="center">
				<img height="208" src="http://dev2dev.bea.com.cn/images/paihang_article/041020/image018.jpg" width="288" />
				<img height="207" src="http://dev2dev.bea.com.cn/images/paihang_article/041020/image020.jpg" width="269" />
		</p>
		<br />
		<p>从截屏画面上可以看到Weblogic Server对所有的应用程序设置的cookie的路径都是/，这是不是意味着在Weblogic Server中默认的就可以共享session了呢？然而一个小实验即可证明即使不同的应用程序使用的是同一个session，各个应用程序仍然只能访问自己所设置的那些属性。这说明Weblogic Server中的session的内存结构可能如下<br /></p>
		<br />
		<p align="center">
				<img height="290" src="http://dev2dev.bea.com.cn/images/paihang_article/041020/image022.jpg" width="420" />
		</p>
		<br />
		<p>对于这样一种结构，在session机制本身上来解决session共享的问题应该是不可能的了。除了借助于第三方的力量，比如使用文件、数据库、JMS或者客户端cookie，URL参数或者隐藏字段等手段，还有一种较为方便的做法，就是把一个应用程序的session放到 ServletContext中，这样另外一个应用程序就可以从ServletContext中取得前一个应用程序的引用。示例代码如下，</p>
		<br />
		<p>应用程序A<br />context.setAttribute("appA", session); </p>
		<br />
		<p>应用程序B<br />contextA = context.getContext("/appA");<br />HttpSession sessionA = (HttpSession)contextA.getAttribute("appA"); </p>
		<br />
		<p>值得注意的是这种用法不可移植，因为根据ServletContext的JavaDoc，应用服务器可以处于安全的原因对于context.getContext("/appA");返回空值，以上做法在Weblogic Server 8.1中通过。</p>
		<br />
		<p>那么Weblogic Server为什么要把所有的应用程序的cookie路径都设为/呢？原来是为了SSO，凡是共享这个session的应用程序都可以共享认证的信息。一个简单的实验就可以证明这一点，修改首先登录的那个应用程序的描述符weblogic.xml，把cookie路径修改为/appA访问另外一个应用程序会重新要求登录，即使是反过来，先访问cookie路径为/的应用程序，再访问修改过路径的这个，虽然不再提示登录，但是登录的用户信息也会丢失。注意做这个实验时认证方式应该使用FORM，因为浏览器和web服务器对basic认证方式有其他的处理方式，第二次请求的认证不是通过session来实现的。具体请参看[7] secion 14.8 Authorization，你可以修改所附的示例程序来做这些试验。</p>
		<br />
		<p>八、总结<br />session机制本身并不复杂，然而其实现和配置上的灵活性却使得具体情况复杂多变。这也要求我们不能把仅仅某一次的经验或者某一个浏览器，服务器的经验当作普遍适用的经验，而是始终需要具体情况具体分析。</p>
		<img height="1" alt="" src="http://c.services.spaces.live.com/CollectionWebService/c.gif?space=stieglitzcc&amp;page=RSS%ef%bc%9aSession%e8%af%a6%e8%a7%a3&amp;referrer=" width="1" border="0" />
		<img style="POSITION: absolute" height="0px" alt="" src="http://c.live.com/c.gif?NC=31263&amp;NA=1149&amp;PI=81873&amp;RF=&amp;DI=3919&amp;PS=85545&amp;TP=stieglitzcc.spaces.live.com&amp;GT1=stieglitzcc%3b2052" width="0px" />
		<br />
		<strong>发布日期： </strong>一, 09 一月 2006 12:49:53 GMT<br /><img src ="http://www.blogjava.net/xiaosao/aggbug/93898.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/xiaosao/" target="_blank">cAng^Er</a> 2007-01-15 11:28 <a href="http://www.blogjava.net/xiaosao/articles/93898.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>web一些值得珍藏的代码</title><link>http://www.blogjava.net/xiaosao/articles/93880.html</link><dc:creator>cAng^Er</dc:creator><author>cAng^Er</author><pubDate>Mon, 15 Jan 2007 02:33:00 GMT</pubDate><guid>http://www.blogjava.net/xiaosao/articles/93880.html</guid><wfw:comment>http://www.blogjava.net/xiaosao/comments/93880.html</wfw:comment><comments>http://www.blogjava.net/xiaosao/articles/93880.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/xiaosao/comments/commentRss/93880.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/xiaosao/services/trackbacks/93880.html</trackback:ping><description><![CDATA[&nbsp;&nbsp;&nbsp;&nbsp; 摘要: 1. 								oncontextmenu								=								"window.event.returnValue=false"								 将彻底屏蔽鼠标右键								&lt;								table								 border 								oncontextmenu								=								return		...&nbsp;&nbsp;<a href='http://www.blogjava.net/xiaosao/articles/93880.html'>阅读全文</a><img src ="http://www.blogjava.net/xiaosao/aggbug/93880.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/xiaosao/" target="_blank">cAng^Er</a> 2007-01-15 10:33 <a href="http://www.blogjava.net/xiaosao/articles/93880.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item></channel></rss>