今天一个同事问一个关于Tabpane的问题,说要做成Wizard的格式,用Session保存数据好,还是把数据随着request传递,隐藏在hidden表单域呢?我说,无论用那个,感觉都不爽。
放在session:wizard如果next多几步,数据放在session里,明显不妥,系统的Application、session这样的对象,是受严格控制,不能随便由程序员操作的。数据量大了,单机、集群的效率都会受到影响;而且,如果用户next了一半,然后关掉页面,干其它的去了,数据要一直等到session过期才失效。。。
放在request:每次next、previous,数据都要跟着request屁股后面跑,实在是不爽,况且,安全也是个问题。
是时候引出continuation了。什么是continuation?最简单的说,比如,你的程序有两行代码,continuation能保证你的程序在执行了第一行之后return,下次你再进入此程序,如果有个类似于“continuationId”的东东相同,程序就会从第二行代码开始执行。也就是说,程序有了自身状态的管理,有了“记忆”。
这么好的东东做Wizard实在是太适合了,可惜,Java语言本身并不支持此功能。于是,一些大牛们遍开始在framework级别搞这个,比如Java Framework支持continuation的有:Apache Cocoon 2、RIFE、Spring Web flow以及WebWork2(使用RIFE的实现)听说jetty6将在Web Server级别提供continuation的实现,实在是不错,google了一下,可惜还只是beta版。不过,看了一篇文章,里面介绍了如何在jetty6中使用continuatio,具体代码不贴了,感兴趣的可以自己看(http://chimpen.com/typo/articles/2006/01/15/jetty-6-continuations)。配置文件如下:
<Set name="connectors">
<Array type="org.mortbay.jetty.Connector">
<Item>
<New class="org.mortbay.jetty.nio.SelectChannelConnector">
<Set name="port">80</Set>
<Set name="maxIdleTime">50000</Set>
<Set name="Acceptors">1</Set>
</New>
</Item>
</Array>
</Set>
有了continuation,有了maxIdleTime,正好解决了使用request、sesssion一半的问题。怎么说是一半呢?目前的continuation,据我所知,只支持到单机的程度,集群下就不行了,这方面,使用request显然更合适;而且,各个框架或Web Server的实现机理是不是用到了session也未为可知,不知道究竟效率如何。。。
sigh,跑了半天,又跑回原地,看来得还是继续使用request比较划算。用老大的话说,宁可让程序员不爽一点,也不能让服务器不爽。。。汗!
continuation需要解决的两个问题:集群环境下continuation状态复制;性能问题。
基于其它框架及语言的实现,如Seaside,一个基于Smalltalk的的Web框架、Ruby等等,不再一列举,
意义不大,感兴趣的,可以看看,参考一下。
一些参考资料:
phl: Jetty 6 Continuations
http://chimpen.com/typo/articles/2006/01/15/jetty-6-continuations
Jetty 6.0 Continuations - AJAX Ready!
http://www.mortbay.com/MB/log/gregw/?permalink=Jetty6Continuations.html
tss: A Stateless Web experience with continuation server
http://www.theserverside.com/news/thread.tss?thread_id=39579
ibm: 用 continuation 开发复杂的 Web 应用程序
http://www-128.ibm.com/developerworks/cn/java/j-contin.html?ca=dwcn-newsletter-java
ibm: 轻量级开发的成功秘诀,第 9 部分: 基于 Continuation 的框架
http://www-128.ibm.com/developerworks/cn/opensource/os-lightweight9/
csdn: 从Continuation说起
http://kb.csdn.net/java/Articles/200507/e365b18a-a8f0-4534-a4f7-616ccab179b2.html