??xml version="1.0" encoding="utf-8" standalone="yes"?>国产欧美一区二区精品久导航,久久久久久久久国产精品,天堂av在线http://www.aygfsteel.com/batistuta/articles/84333.htmlbatistutabatistutaWed, 29 Nov 2006 05:36:00 GMThttp://www.aygfsteel.com/batistuta/articles/84333.htmlhttp://www.aygfsteel.com/batistuta/comments/84333.htmlhttp://www.aygfsteel.com/batistuta/articles/84333.html#Feedback0http://www.aygfsteel.com/batistuta/comments/commentRss/84333.htmlhttp://www.aygfsteel.com/batistuta/services/trackbacks/84333.html(zhn)可通过命o(h)行?SubversionQ但若将其与(zhn)的 IDE 集成更ؓ(f)便捷。IntelliJ IDEA 5.0 ?qing)后l版本均包含?Subversion 的内|支持。NetBeans q不支持 SubversionQ但相关工作已经在开展,未来版本中将提供支持。对?EclipseQ?zhn)需要安?Subclipse 插g。本文?Eclipse 作ؓ(f) IDE?/p>

Subclipse 的安装与其他 Eclipse 插gcMQ?/p>

  1. ?Eclipse 中,选择 Help Software Updates | Find and Install...?br />
  2. 在向导的W一个面板中Q单?Search for new features to install 单选按钮,q单?Next?br />
  3. 在向导的W二个面板中Q单?New Remote Site。输?Subclipse 作ؓ(f)名称Q输?http://subclipse.tigris.org/update_1.0.x 作ؓ(f) URL。然后单?Finish?

    q将启动另外一个小的向对{下一个对话框应ؓ(f)(zhn)提供一个可安装的特?—?Subclipse。选中它ƈ单击 Next?br />
  4. 接受许可协议Q完成安装?br />

E序包目前未l过数字{֐Q但只要(zhn)是按照W三步的 URL 下蝲的,是安全的?/p>
Subversion 快捷方式

如果(zhn)目前常怋?SubversionQ?zhn)可能希望其d?Eclipse ?New、Open Perspective ?Show View 菜单中。ؓ(f)此,选择 Window/Customize Perspective... q在 Shortcut 分类列表中选中 SVN。这(zhn)可在目前可看到 CVS 的所有菜单中讉K Subversion?/p>

安装E序包后Q?zhn)必须重新启?EclipseQ随后才能?Subversion。完成之后,(zhn)就可以与如今?CVS 大体相同的方式?Subversion ?jin),只有为数不多的区别?/p>

(g)出项?/font>

讄一个新?Subversion 存储库,特别是网l存储库相对来说较ؓ(f)复杂。但若?zhn)正在q接一个现有项目,W一ơ检出文件就相当L。在 File 菜单中选择 New/Other...。这些步骤将为?zhn)打开??1 所C的对话框:(x)


?1. 通过 Subversion 启动一个新目
通过 SVN (g)出项? hspace=

接下来,打开 SVN 文g夹,选择 Select Checkout Projects from SVNQƈ单击 Next 以显C如?2 所C的对话框:(x)


?2. Select/Create Location
Select/Create Location

W一ơ从存储库检出时Q?zhn)需要选择 Create a new repository location q单?Next。这ؓ(f)(zhn)打开如图 3 所C的对话框:(x)


?3. 为存储库键入 URL
为存储库键入 URL

(zhn)在q里提供存储库的 URL。这只是一个普通的 http URLQ如 http://svn.apache.org/repos/asf/xerces/java/。这一ơ单?Next ӞEclipse q接到存储库Qƈ查找可检出的文g夏V通常有三个文件夹Qbranches、tags ?trunkQ如?4 所C。Branches 文g夹用于试验。Tags 通常标识较老的、已发布的Y件版本。而大多数时候,(zhn)都希望在主分支上工作(CVS UC?HEADQ,因此选择 trunk q单?Next?/p>
?4. 选择要检出的修订?/b>
选择文g? hspace=

(zhn)现在有两个选择Q?b>Check out as a Project configured using the New Project Wizard ?Check out as a project in the workspaceQ如?5 所C。?zhn)可按自己的需要Q意选择Q?zhn)可能希望为项目命名,因?f)默认名称?“trunk”。最后,单击 Finish?/p>
?5. (g)出项目的两种Ҏ(gu)
(g)出项目的两种Ҏ(gu)

Eclipse 现在从?zhn)选择的分支、主q或标记中下载所有源文g。如果?zhn)选择的是 Check out as a project in the workspaceQ则必须完成 Eclipse ?New Project 向导Q以讄~译器别、项目布局和其他选项。如果?zhn)未?New Project 向导Q则需要手动设|构\径和其他选项Q就像?zhn)在自q文gpȝ的一个目录中创徏?jin)一个项目那栗确实,(zhn)所做的与那极ؓ(f)怼。所有文仉是本地存储的。对于构建、运行和调试q样的普通操作,Eclipse 不关?j)文件是否已为版本控制检出?/p>



回页?/b>


验证讄

此时Q最好进行一ơ快速、明智的(g)查,保(zhn)已正确地设|了(jin)构徏路径。如果没有明昄问题Qƈ且能够运行单元测试,那么卛_攑ֿ(j)地l下M(jin)?/p>

如果存在问题Q检查项目属性,以确保正地讄?jin)源路径和类路径。之差一非常常见Q无论是多一q是一。因此,最l?Eclipse ?x)认为(zhn)的类的名U类g src.org.apache.xerces.parsers.SAXParser ?apache.xerces.parsers.SAXParserQ而不?org.apache.xerces.parsers.SAXParser。在多文件夹目中,Eclilpse 也常怼(x)错误地将一个数据文件夹标记为源文gҎ(gu)遗漏?jin)一个源文g夏V如果发生了(jin)以上M一U小故障Q?zhn)都必M复错误,然后才能基础?/p>
多文件提?/b>

Subversion 可在一个原子操作中提交C文gQ与之Ş成对比,CVS 每一个分开的文件视Zơ独立提交)(j)。ؓ(f)此,只需?Package Explorer 中选择(zhn)想提交的所有文Ӟ按住 ctrl 键或 Command 键,然后依次单击所需文gQ,然后在上下文菜单中选择 Team/Commit... 卛_。如果?zhn)随后需要取消更Ҏ(gu)存储库回复到特定更改之前的状态,q种Ҏ(gu)非常有用?/p>

要检查错误,选择 Project | PropertiesQ然后找?Java Build Path。?zhn)可?source 选项卡中修订M向导做错的地斏V?zhn)可能q要d另外一个项目需要的 JAR 归档QEclpse 在检出时不会(x)注意到此归档。?zhn)q可?library 选项卡的 Java Build Path 中添加此归档?/p>

请做好心(j)理准备,(zhn)可能要在这里花上一Ҏ(gu)间。Eclipse 很少?x)在W一ơ就让一切正无误,每个目l织其文件和库的方式又M(x)有所不同?/p>

与存储库同步

接下来?zhn)可以照常编辑文件?jin)。作出?zhn)希望的Q何更攏V运行单元测试。优化代码。更正注释中的拼写错误。完成部分工作后Q用上下文菜单q择 Team/Commit...。?zhn)看到?6 所C的对话框,要求(zhn)输入提交注释:(x)


?6. Subclipse 的提交对话框
提交

同样Q若其他人更改了(jin)(zhn)希望应用于(zhn)的副本的存储库Q只要在 Package Explorer 中选中文gQƈ从上下文菜单中选择 Team/Update 卛_。这?x)以d本替换?zhn)的副本?/p>



回页?/b>


合ƈ

如果(zhn)已q行?jin)更改,其他开发h员也q行?jin)更改,那么?zhn)就必须手动合ƈ文g。对于绝大多数简单更改,Subversion 可推断出需要进行怎样的处理,无需人工q预。但对于较大、较为复杂、存在冲H的更改Q?zhn)可能需要参与进来,手动合ƈ更改?/p>

Subclipse 在这里可提供一些帮助,但实际上我发玎ͼ在一个独立的H口或选项卡中直接实现一个(f)时文件副本,通过存储库更新本地副本以覆盖我的更改Q然后通过临时副本重新输入更改Q这样做往往更容易。若存储库中的更改与我做出的更改相比较少Q我׃(x)从存储库实现临时副本Qƈ通过它进行提交,而不是更新。随后我?x)重新应用那些更攏V这听上去非常复杂,但事实通常q如此Q它的发生几率几乎与(zhn)希望的一样低。即便是(zhn)出?jin)错Q忘记重新应用更Ҏ(gu)是错误地应用?jin)更改,L可以扑ֈ所有更改的完整历史Q包括?zhn)覆盖的那些更改?j)供?zhn)参考。实际上(zhn)从未彻底丢׃Q何东ѝ?/p>

如果(zhn)不定已更改了(jin)哪些文gQ同步视囑֏以ؓ(f)(zhn)显C些文件。?zhn)q可打开标签修饰Qlabel decorationQ来查看上次提交/更新后哪些文件发生过更改。选择 Help | PreferencesQ然后再选择 General/Appearance/Label Decorations。然后选中 SVN 复选框。(实际上该复选框在默认情况下是选中的。)(j)





回页?/b>


修补

如果(zhn)不具备正在使用的存储库的提交权限,需要制作一个修补程序,然后其发送给l护人员。只要选中(zhn)希望比较的文gQ然后从上下文菜单中选择 Team/Create Patch... 卛_。?zhn)可以随自q方便修补程序保存到文g或剪贴板中。随后可通过?sh)子邮g其发送给l护人员Q或者在 bug 报告中附上该修补E序。修补程序本w采用的格式?CVS 所使用?diff 格式相同?/p>

应用他h发送给(zhn)的修补E序没那么复杂?jin),只要选中(zhn)想修补的文件或目。从上下文菜单中选择 Team/Apply Patch... Q然后^C惯用?open file 对话框选择修补E序文g卛_?/p>



回页?/b>


比较

如果(zhn)已作出?jin)一些更改,q且希望看看(zhn)的副本与存储库中的版本有怎样的差别,只需在上下文菜单中选择 Compare/Latest From Repository 卛_。这实际上与 CVS 中比较功能的工作方式完全相同。图 7 昄?jin)比较功能的工作情况Q?/p>
?7. ?Subclipse 中比较两个文?/b>





回页?/b>


删除

删除文g也很L。只要在 Eclipse 的程序包理器中删除文gQ然后提交父文g夹即可。删除目录要略微复杂一炏V?zhn)可以选择一个目录ƈ删除它。目录中的所有文件将?x)立卌删除。但在?zhn)删除后,目录本n?qing)其所有子目录又会(x)立即出现在原来的位置。要真正地删除一个文件夹Q?zhn)需要选中 “已删除?的文件夹q提交它。同一规则也适用于将一个文件从一个位|移动到另外一个位|的情况?/p>
心(j)Q?/b>

Apache 目源代码提交C(jin)不属于自己、现在也无法删除?Subversion 存储库中Q自己陷入ȝ(ch)。Apache 可以隐藏代码Q但如果(zhn)知道到哪儿ȝQ?zhn)会(x)发现这些代码就在那ѝ拥有源代码的h可能是恶意的Q也有可能向 Apache ?ISP 发送一?DMCA 下线通知Q从而 Apache q Internet。Apache 惟一的防御措施就是彻底删除其存储库?/p>

在?zhn)删除了(jin)一个文件或一个文件夹之后Q依然可以通过存储库其还原,即便是已l提交了(jin)删除。一旦?zhn)Q何内Ҏ(gu)q存储库Q那么就永远不会(x)真正、永久地失去它,q有时候会(x)产生问题。例如,假设(zhn)发现有人意外的(g)入了(jin)其整个主目录Q包括其 Quicken 数据文g和所有来自其׃h的情书归档。?zhn)很希望能?i>d消除 q些被误提交的文Ӟq样׃?x)有其他人得到这些文件。尽这是一个非同寻常的操作Q无论如何,版本控制pȝ的目的就在于永远C留每一个文件的每个修订版)(j)Q但有时也是必要的。o(h)人沮丧的是,Subversion 漏掉?jin)这个重要的?gu)?/p>

׃没有d消除的命令,所以我在ؓ(f)外部可见的存储库使用 Subversion 旉怸安。CVS 也没有这L(fng)命o(h)Q但?CVS 中,(zhn)完全有可能在不毁掉存储库的情况下手动删除错误提交的文g?/p>



回页?/b>


l束?/font>

对于内部存储库,Subversion 提供?jin)远?CVS 的改q。如果添加了(jin)某种cd的彻底消除功能,它也应同样适于外部存储库。尽像 Eclipse q样的工具对 Subversion 的第三方支持q不?CVS 支持那样普遍Q但形势正在q速地发生变化。Subversion ?x)成为新目的默认源代码存储库。尚无源代码控制的现有项目应快(g)?Subversion。而已?CVS 存储库的现有目可能仍在观望Q希望等C们所依赖的全部工具均全面支持 Subversion 后再q行切换。但q些目最l也?x)移植?Subversion。Subversion 中的改进如此显著Qo(h)人难以忽略。未来必属?Subversion?/p>



回页?/b>


参考资?

学习(fn)
  • (zhn)可以参阅本文在 developerWorks 全球站点上的 英文原文 ?br />
  • ?a >Sharing code with the Eclipse Platform”(Pawel LeszekQdeveloperWorksQ?003 q?3 月)(j)Q简要介l了(jin) Eclipse q_处理源代码版本控制的方式?br />
  • ?a >利用 PHP ?Subversion 从零开始创Z?blog”(Tyler AndersonQdeveloperWorkQ?006 q?2 月)(j)Q一份介l?PHP ?Subversion q行 Web 开发的教程?br />
  • ?a >自动q行团队构徏和单元测试过E?/a>”(Mark WilkinsonQdeveloperWorksQ?005 q?10 月)(j)Q创Z个自动化pȝQ以使用 CVS ?SubversionQ及(qing)其他工具Q构建ƈ试(zhn)的源代码?br />
  • ?a >Pragmatic Version Control using Subversion, 2nd Edition”(Mike MasonQPragmatic ProgrammersQ?006 q?5 月)(j)Q全面的 Subversion 用法介绍?br />
  • Version Control with Subversion QBen Collins-SussmanQBrian W. FitzpatrickQC. Michael PilatoQO'Reilly MediaQ关?Subversion 的免费在U图书?br />
  • SourceforgeQؓ(f)开放源码项目提供免费的 Subversion 宿主?br />
  • Java 技术专?/a>Q数癄关于 Java ~程各个斚w的文章?/li>

获得产品和技?/b>
  • SubversionQ针对不同^台的开放源码及(qing)二进制版本?br />
  • SubclipseQEclipse Subversion 插g?br />
  • TeepeeQNetBeans Subversion 目?br />
  • TMateQIntelliJ IDEA Subversion 插g?br />

讨论


batistuta 2006-11-29 13:36 发表评论
]]>
关于session的详l解?http://www.aygfsteel.com/batistuta/articles/84302.htmlbatistutabatistutaWed, 29 Nov 2006 03:22:00 GMThttp://www.aygfsteel.com/batistuta/articles/84302.htmlhttp://www.aygfsteel.com/batistuta/comments/84302.htmlhttp://www.aygfsteel.com/batistuta/articles/84302.html#Feedback0http://www.aygfsteel.com/batistuta/comments/commentRss/84302.htmlhttp://www.aygfsteel.com/batistuta/services/trackbacks/84302.html  在我的经验里Qsessionq个词被滥用的程度大概仅ơ于transactionQ更加有的是transaction与session在某些语境下的含义是相同的?/p>

  sessionQ中文经常翻译ؓ(f)?x)话Q其本来的含义是指有始有l的一pd动作/消息Q比如打?sh)话时从拿v?sh)话拨号到挂断?sh)话这中间的一pdq程可以UCZ个session。有时候我们可以看到这L(fng)话“在一个浏览器?x)话期间Q?..”,q里的会(x)话一词用的就是其本义Q是指从一个浏览器H口打开到关闭这个期间①。最混ؕ的是“用P客户端)(j)在一ơ会(x)话期间”这样一句话Q它可能指用L(fng)一pd动作Q一般情况下是同某个具体目的相关的一pd动作Q比如从d到选购商品到结账登?gu)样一个网上购物的q程Q有时候也被称Z个transactionQ,然而有时候也可能仅仅是指一ơ连接,也有可能是指含义①,其中的差别只能靠上下文来推断②?/p>

  然而当session一词与|络协议相关联时Q它又往往隐含?jin)“面向连接”和/或“保持状态”这样两个含义,“面向连接”指的是在通信双方在通信之前要先建立一个通信的渠道,比如打电(sh)话,直到Ҏ(gu)接了(jin)?sh)话通信才能开始,与此相对的是写信Q在你把信发出去的时候你q不能确认对方的地址是否正确Q通信渠道不一定能建立Q但对发信h来说Q通信已经开始了(jin)。“保持状态”则是指通信的一方能够把一pd的消息关联v来,使得消息之间可以互相依赖Q比如一个服务员能够认出再次光(f)的老顾客ƈ且记得上ơ这个顾客还?gu)Ơ店里一块钱。这一cȝ例子有“一个TCP session”或者“一个POP3 session”③?/p>

  而到?jin)web服务器蓬勃发展的时代Qsession在web开发语境下的语义又有了(jin)新的扩展Q它的含义是指一cȝ来在客户端与服务器之间保持状态的解决Ҏ(gu)④。有时候session也用来指q种解决Ҏ(gu)的存储结构,如“把xxx保存在session里”⑤。由于各U用于web开发的语言在一定程度上都提供了(jin)对这U解x案的支持Q所以在某种特定语言的语境下Qsession也被用来指代该语a的解x案,比如l常把Java里提供的 javax.servlet.http.HttpSessionUCؓ(f)session⑥?/p>

  鉴于q种混ؕ已不可改变,本文中session一词的q用也会(x)Ҏ(gu)上下文有不同的含义,请大家注意分辨?/p>

  在本文中Q用中文“浏览器?x)话期间”来表达含义①,使用“session机制”来表达含义④,使用“session”表辑֐义⑤Q用具体的“HttpSession”来表达含义?/p>

  二、HTTP协议与状态保?/p>

  HTTP协议本n是无状态的Q这与HTTP协议本来的目的是相符的,客户端只需要简单的向服务器h下蝲某些文gQ无论是客户端还是服务器都没有必要纪录彼此过ȝ行ؓ(f)Q每一ơ请求之间都是独立的Q好比一个顾客和一个自动售货机或者一个普通的Q非?x)员Ӟ?j)大卖Z间的关系一栗?/p>

  然而聪明(或者贪?j)?Q的Z很快发现如果能够提供一些按需生成的动态信息会(x)使web变得更加有用Q就像给有线?sh)视加上?gu)功能一栗这U需求一斚wqHTML逐步d?jin)表单、脚本、DOM{客L(fng)行ؓ(f)Q另一斚w在服务器端则出现?jin)CGI规范以响应客L(fng)的动态请求,作ؓ(f)传输载体的HTTP协议也添加了(jin)文g上蝲、cookieq些Ҏ(gu)。其中cookie的作用就是ؓ(f)?jin)解决HTTP协议无状态的~陷所作出的努力。至于后来出现的session机制则是又一U在客户端与服务器之间保持状态的解决Ҏ(gu)?/p>

  让我们用几个例子来描qC下cookie和session机制之间的区别与联系。笔者曾l常ȝ一家咖啡店有喝5杯咖啡免费赠一杯咖啡的优惠Q然而一ơ性消?杯咖啡的Z(x)微乎其微Q这时就需要某U方式来U录某位֮的消Ҏ(gu)量。想象一下其实也无外乎下面的几种Ҏ(gu)Q?/p>

  1、该店的店员很厉宻I能记住每位顾客的消费数量Q只要顾客一走进咖啡店,店员q道该怎么对待?jin)。这U做法就是协议本w支持状态?/p>

  2、发l顾客一张卡片,上面记录着消费的数量,一般还有个有效期限。每ơ消Ҏ(gu)Q如果顾客出C张卡片,则此ơ消费就?x)与以前或以后的消费相联pv来。这U做法就是在客户端保持状态?/p>

  3、发l顾客一张会(x)员卡Q除?jin)卡号之外什么信息也不纪录,每次消费Ӟ如果֮出示该卡片,则店员在店里的纪录本上找到这个卡号对应的U录d一些消费信息。这U做法就是在服务器端保持状态?/p>

  ׃HTTP协议是无状态的Q而出于种U考虑也不希望使之成ؓ(f)有状态的Q因此,后面两种Ҏ(gu)成为现实的选择。具体来说cookie机制采用的是在客L(fng)保持状态的Ҏ(gu)Q而session机制采用的是在服务器端保持状态的Ҏ(gu)。同时我们也看到Q由于采用服务器端保持状态的Ҏ(gu)在客L(fng)也需要保存一个标识,所以session机制可能需要借助于cookie机制来达C存标识的目的Q但实际上它q有其他选择?/p>

  三、理解cookie机制

  cookie机制的基本原理就如上面的例子一L(fng)单,但是q有几个问题需要解冻I(x)“会(x)员卡”如何分发;“会(x)员卡”的内容Q以?qing)客户如何用“会(x)员卡”?/p>

  正统的cookie分发是通过扩展HTTP协议来实现的Q服务器通过在HTTP的响应头中加上一行特D的指示以提C浏览器按照指示生成相应的cookie。然而纯_的客户端脚本如JavaScript或者VBScript也可以生成cookie?/p>

  而cookie的用是由浏览器按照一定的原则在后台自动发送给服务器的。浏览器(g)查所有存储的cookieQ如果某个cookie所声明的作用范围大于等于将要请求的资源所在的位置Q则把该cookie附在h资源的HTTPh头上发送给服务器。意思是麦当劳的?x)员卡只能在麦当劳的店里出示Q如果某家分店还发行?jin)自q?x)员卡,那么q这家店的时候除?jin)要出示麦当劳的会(x)员卡,q要出示q家店的?x)员卡?/p>

  cookie的内容主要包括:(x)名字Q|q期旉Q\径和域?/p>

  其中域可以指定某一个域比如.google.comQ相当于d招牌Q比如宝z公司,也可以指定一个域下的具体某台机器比如www.google.com或者f(xi)roogle.google.comQ可以用飘柔来做比?/p>

  路径是跟在域名后面的URL路径Q比?或?foo{等Q可以用某飘柔专柜做比?/p>

  路径与域合在一起就构成?jin)cookie的作用范围?/p>

  如果不设|过期时_(d)则表C个cookie的生命期为浏览器?x)话期间Q只要关闭浏览器H口Qcookie消׃(jin)。这U生命期为浏览器?x)话期的cookie被称Z(x)话cookie。会(x)话cookie一般不存储在硬盘上而是保存在内存里Q当然这U行为ƈ不是规范规定的。如果设|了(jin)q期旉Q浏览器׃(x)把cookie保存到硬盘上Q关闭后再次打开览器,q些cookie仍然有效直到过讑֮的过期时间?/p>

  存储在硬盘上的cookie可以在不同的览器进E间׃nQ比如两个IEH口。而对于保存在内存里的cookieQ不同的览器有不同的处理方式。对于IEQ在一个打开的窗口上按Ctrl-NQ或者从文g菜单Q打开的窗口可以与原窗口共享,而用其他方式新开的IEq程则不能共享已l打开的窗口的内存cookieQ对于Mozilla Firefox0.8Q所有的q程和标{N都可以共享同L(fng)cookie。一般来说是用javascript的window.open打开的窗口会(x)与原H口׃n内存cookie。浏览器对于?x)话cookie的这U只认cookie不认人的处理方式l常l采用session机制的web应用E序开发者造成很大的困扰?/p>

  下面是一个goolge讄cookie的响应头的例?/p>

HTTP/1.1 302 Found
Location: http://www.google.com/intl/zh-CN/
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
Content-Type: text/html

 四、理解session机制

 session机制是一U服务器端的机制Q服务器使用一U类g散列表的l构Q也可能是使用散列表)(j)来保存信息?/p>

  当程序需要ؓ(f)某个客户端的h创徏一个session的时候,服务器首先检查这个客L(fng)的请求里是否已包含了(jin)一个session标识 - UCؓ(f)session idQ如果已包含一个session id则说明以前已lؓ(f)此客L(fng)创徏qsessionQ服务器按照session id把这个session(g)索出来用(如果(g)索不刎ͼ可能?x)新Z个)(j)Q如果客L(fng)h不包含session idQ则为此客户端创Z个sessionq且生成一个与此session相关联的session idQsession id的值应该是一个既不会(x)重复Q又不容易被扑ֈ规律以仿造的字符Ԍq个session id被在本ơ响应中q回l客L(fng)保存?/p>

  保存q个session id的方式可以采用cookieQ这样在交互q程中浏览器可以自动的按照规则把q个标识发挥l服务器。一般这个cookie的名字都是类g SEEESIONIDQ而。比如weblogic对于web应用E序生成的cookieQJSESSIONID= ByOK3vjFD75aPnrF7C2HmdnV6QZcEbzWoWiBYEnLerjQ99zWpBng!-145788764Q它的名字就?JSESSIONID?/p>

  ׃cookie可以被h为的止Q必L其他机制以便在cookie被禁止时仍然能够把session id传递回服务器。经常被使用的一U技术叫做URL重写Q就是把session id直接附加在URL路径的后面,附加方式也有两种Q一U是作ؓ(f)URL路径的附加信息,表现形式为http://...../xxx; jsessionid=ByOK3vjFD75aPnrF7C2HmdnV6QZcEbzWoWiBYEnLerjQ99zWpBng!-145788764 另一U是作ؓ(f)查询字符串附加在URL后面Q表现Ş式ؓ(f)http://...../xxx?jsessionid= ByOK3vjFD75aPnrF7C2HmdnV6QZcEbzWoWiBYEnLerjQ99zWpBng!-145788764
q两U方式对于用h说是没有区别的,只是服务器在解析的时候处理的方式不同Q采用第一U方式也有利于把session id的信息和正常E序参数区分开来?/p>

  Z(jin)在整个交互过E中始终保持状态,必d每个客户端可能请求的路径后面都包含这个session id?/p>

  另一U技术叫做表单隐藏字Dc(din)就是服务器?x)自动修改表单,d一个隐藏字D,以便在表单提交时能够把session id传递回服务器。比如下面的表单

<form name="testform" action="/xxx">
<input type="text">
</form>

  在被传递给客户端之前将被改写成

<form name="testform" action="/xxx">
<input type="hidden" name="jsessionid" value="ByOK3vjFD75aPnrF7C2HmdnV6QZcEbzWoWiBYEnLerjQ99zWpBng!-145788764">
<input type="text">
</form>

  q种技术现在已较少应用Q笔者接触过的很古老的iPlanet6(SunONE应用服务器的前n)׃用了(jin)q种技术。实际上q种技术可以简单的用对action应用URL重写来代ѝ?/p>

  在谈论session机制的时候,常常听到q样一U误解“只要关闭浏览器Qsession消׃(jin)”。其实可以想象一下会(x)员卡的例子,除非֮d对店家提出销卡,否则店家l对不会(x)L删除֮的资料。对session来说也是一L(fng)Q除非程序通知服务器删除一个sessionQ否则服务器?x)一直保留,E序一般都是在用户做log off的时候发个指令去删除session。然而浏览器从来不会(x)d在关闭之前通知服务器它?yu)要关闭Q因此服务器Ҏ(gu)不会(x)有机?x)知道浏览器已经关闭Q之所以会(x)有这U错觉,是大部分session机制都用会(x)话cookie来保存session idQ而关闭浏览器后这个session id消׃(jin)Q再ơ连接服务器时也无法找到原来的session。如果服务器讄的cookie被保存到盘上,或者用某U手D|写浏览器发出?HTTPh_(d)把原来的session id发送给服务器,则再ơ打开览器仍然能够找到原来的session?/p>

  恰恰是由于关闭浏览器不会(x)Dsession被删除,q服务器ؓ(f)seesion讄?jin)一个失效时_(d)当距dL(fng)上一ơ用session的时间超q这个失效时间时Q服务器可以认为客L(fng)已经停止?jin)活动,才?x)把session删除以节省存储空间?/p>

  五、理解javax.servlet.http.HttpSession

  HttpSession是Javaq_对session机制的实现规范,因ؓ(f)它仅仅是个接口,具体到每个web应用服务器的提供商,除了(jin)对规范支持之外,仍然?x)有一些规范里没有规定的细微差异。这里我们以BEA的Weblogic Server8.1作ؓ(f)例子来演C?/p>

  首先QW(xu)eblogic Server提供?jin)一pd的参数来控制它的HttpSession的实玎ͼ包括使用cookie的开关选项Q用URL重写的开关选项Qsession持久化的讄Qsession失效旉的设|,以及(qing)针对cookie的各U设|,比如讄cookie的名字、\径、域Qcookie的生存时间等?/p>

  一般情况下Qsession都是存储在内存里Q当服务器进E被停止或者重启的时候,内存里的session也会(x)被清I,如果讄?session的持久化Ҏ(gu),服务器就?x)把session保存到硬盘上Q当服务器进E重新启动或q些信息能够被再次使用QW(xu)eblogic Server支持的持久性方式包括文件、数据库、客L(fng)cookie保存和复制?/p>

  复制严格说来不算持久化保存,因ؓ(f)session实际上还是保存在内存里,不过同样的信息被复制到各个cluster内的服务器进E中Q这样即使某个服务器q程停止工作也仍然可以从其他q程中取得session?/p>

  cookie生存旉的设|则?x)?jing)响浏览器生成的cookie是否是一个会(x)话cookie。默认是使用?x)话cookie。有兴趣的可以用它来试验我们在第四节里提到的那个误解?/p>

  cookie的\径对于web应用E序来说是一个非帔R要的选项QW(xu)eblogic Server对这个选项的默认处理方式得它与其他服务器有明昄区别。后面我们会(x)专题讨论?/p>

  关于session的设|参考[5] http://e-docs.bea.com/wls/docs70/webapp/weblogic_xml.html#1036869

  六、HttpSession常见问题

  Q在本小节中session的含义ؓ(f)⑤和⑥的混合Q?/p>

  1、session在何时被创徏

  一个常见的误解是以为session在有客户端访问时p创徏Q然而事实是直到某server端程序调?HttpServletRequest.getSession(true)q样的语句时才被创徏Q注意如果JSP没有昄的?<%@page session="false"%> 关闭sessionQ则JSP文g在编译成Servlet时将?x)自动加上这样一条语句HttpSession session = HttpServletRequest.getSession(true);q也是JSP中隐含的session对象的来历?/p>

  ׃session?x)消耗内存资源,因此Q如果不打算使用sessionQ应该在所有的JSP中关闭它?/p>

  2、session何时被删?/p>

  l合前面的讨论,session在下列情况下被删除a.E序调用HttpSession.invalidate();或b.距离上一ơ收到客L(fng)发送的session id旉间隔过?jin)session的超时设|?或c.服务器进E被停止Q非持久sessionQ?/p>

  3、如何做到在览器关闭时删除session

  严格的讲Q做不到q一炏V可以做一点努力的办法是在所有的客户端页面里使用javascript代码window.oncolose来监视浏览器的关闭动作,然后向服务器发送一个请求来删除session。但是对于浏览器崩溃或者强行杀死进E这些非常规手段仍然无能为力?/p>

  4、有个HttpSessionListener是怎么回事

  你可以创L(fng)listenerȝ控session的创建和销毁事Ӟ使得在发生这L(fng)事g时你可以做一些相应的工作。注意是 session的创建和销毁动作触发listenerQ而不是相反。类似的与HttpSession有关的listenerq有 HttpSessionBindingListenerQHttpSessionActivationListener?HttpSessionAttributeListener?/p>

  5、存攑֜session中的对象必须是可序列化的?/p>

  不是必需的。要求对象可序列化只是ؓ(f)?jin)session能够在集中被复制或者能够持久保存或者在必要时server能够暂时把session交换出内存。在Weblogic Server的session中放|一个不可序列化的对象在控制C?x)收C个警告。我所用过的某个iPlanet版本如果session中有不可序列化的对象Q在session销毁时?x)有一个ExceptionQ很奇怪?/p>

  6、如何才能正的应付客户端禁止cookie的可能?/p>

  Ҏ(gu)有的URL使用URL重写Q包括超链接Qform的actionQ和重定向的URLQ具体做法参见[6]
http://e-docs.bea.com/wls/docs70/webapp/sessions.html#100770

  7、开两个览器窗口访问应用程序会(x)使用同一个sessionq是不同的session

  参见W三节对cookie的讨论,对session来说是只认id不认人,因此不同的浏览器Q不同的H口打开方式以及(qing)不同的cookie存储方式都会(x)对这个问题的{案有媄(jing)响?/p>

  8、如何防止用h开两个览器窗口操作导致的session混ؕ

  q个问题与防止表单多ơ提交是cM的,可以通过讄客户端的令牌来解冟뀂就是在服务器每ơ生成一个不同的idq回l客L(fng)Q同时保存在 session里,客户端提交表单时必须把这个id也返回服务器Q程序首先比较返回的id与保存在session里的值是否一_(d)如果不一致则说明本次操作已经被提交过?jin)。可以参看《J2EE核心(j)模式》关于表C层模式的部分。需要注意的是对于用javascript window.open打开的窗口,一般不讄q个idQ或者用单独的idQ以防主H口无法操作Q徏议不要再window.open打开的窗口里做修Ҏ(gu)作,q样可以不用设|?/p>

  9、ؓ(f)什么在Weblogic Server中改变session的值后要重新调用一ơsession.setValue
做这个动作主要是Z(jin)在集环境中提示Weblogic Server session中的值发生了(jin)改变Q需要向其他服务器进E复制新的session倹{?/p>

  10、ؓ(f)什么session不见?/p>

  排除session正常失效的因素之外,服务器本w的可能性应该是微乎其微的,虽然W者在iPlanet6SP1加若q补丁的Solaris版本上倒也遇到q;览器插件的可能性次之,W者也遇到q?721插g造成的问题;理论上防火墙或者代理服务器在cookie处理上也有可能会(x)出现问题?/p>

  出现q一问题的大部分原因都是E序的错误,最常见的就是在一个应用程序中去访问另外一个应用程序。我们在下一节讨个问题?/p>

  七、跨应用E序的session׃n

  常常有这L(fng)情况Q一个大目被分割成若干项目开发,Z(jin)能够互不q扰Q要求每个小目作ؓ(f)一个单独的web应用E序开发,可是C(jin)最后突然发现某几个项目之间需要共享一些信息,或者想使用session来实现SSO (single sign on)Q在session中保存login的用户信息,最自然的要求是应用E序间能够访问彼此的session?/p>

  然而按照Servlet规范Qsession的作用范围应该仅仅限于当前应用程序下Q不同的应用E序之间是不能够互相讉KҎ(gu)的session 的。各个应用服务器从实际效果上都遵守了(jin)q一规范Q但是实现的l节却可能各有不同,因此解决跨应用程序session׃n的方法也各不相同?/p>

  首先来看一下Tomcat是如何实现web应用E序之间session的隔ȝQ从Tomcat讄的cookie路径来看Q它对不同的应用E序讄的cookie路径是不同的Q这样不同的应用E序所用的session id是不同的Q因此即使在同一个浏览器H口里访问不同的应用E序Q发送给服务器的session id也可以是不同的?br /> W者以前用q的iPlanet也采用的是同L(fng)方式Q估计SunONE与iPlanet之间不会(x)有太大的差别。对于这U方式的服务器,解决的思\很简单,实际实行h也不难。要么让所有的应用E序׃n一个session idQ要么让应用E序能够获得其他应用E序的session id?/p>

  iPlanet中有一U很单的Ҏ(gu)来实现共享一个session idQ那是把各个应用程序的cookie路径都设?Q实际上应该?NASAppQ对于应用程序来讲它的作用相当于根)(j)?/p>

<session-info>
<path>/NASApp</path>
</session-info>

  需要注意的是,操作׃n的session应该遵@一些编E约定,比如在session attribute名字的前面加上应用程序的前缀Q得setAttribute("name", "neo")变成setAttribute("app1.name", "neo")Q以防止命名I间冲突Q导致互相覆盖?/p>


  在Tomcat中则没有q么方便的选择。在Tomcat版本3上,我们q可以有一些手D|׃nsession。对于版?以上?TomcatQ目前笔者尚未发现简单的办法。只能借助于第三方的力量,比如使用文g、数据库、JMS或者客L(fng)cookieQURL参数或者隐藏字D늭手段?/p>

  我们再看一下Weblogic Server是如何处理session的?br />

Session详解

Session详解

  从截屏画面上可以看到Weblogic ServerҎ(gu)有的应用E序讄的cookie的\径都?Q这是不是意味着在Weblogic Server中默认的可以共享session?jin)呢Q然而一个小实验卛_证明即不同的应用程序用的是同一个sessionQ各个应用程序仍然只能访问自己所讄的那些属性。这说明Weblogic Server中的session的内存结构可能如?br />

Session详解

  对于q样一U结构,在session机制本n上来解决session׃n的问题应该是不可能的?jin)。除?jin)借助于第三方的力量,比如使用文g、数据库、JMS或者客L(fng)cookieQURL参数或者隐藏字D늭手段Q还有一U较为方便的做法Q就是把一个应用程序的session攑ֈ ServletContext中,q样另外一个应用程序就可以从ServletContext中取得前一个应用程序的引用。示例代码如下,

  应用E序A

context.setAttribute("appA", session);

  应用E序B

contextA = context.getContext("/appA");
HttpSession sessionA = (HttpSession)contextA.getAttribute("appA");

  值得注意的是q种用法不可ULQ因为根据ServletContext的JavaDocQ应用服务器可以处于安全的原因对于context.getContext("/appA");q回I|以上做法在Weblogic Server 8.1中通过?/p>

  那么Weblogic ServerZ么要把所有的应用E序的cookie路径都设?呢?原来是ؓ(f)?jin)SSOQ凡是共享这个session的应用程序都可以׃n认证的信息。一个简单的实验可以证明这一点,修改首先d的那个应用程序的描述Wweblogic.xmlQ把cookie路径修改?appA 讉K另外一个应用程序会(x)重新要求dQ即使是反过来,先访问cookie路径?的应用程序,再访问修改过路径的这个,虽然不再提示dQ但是登录的用户信息也会(x)丢失。注意做q个实验时认证方式应该用FORMQ因为浏览器和web服务器对basic认证方式有其他的处理方式Q第二次h的认证不是通过 session来实现的。具体请参看[7] secion 14.8 AuthorizationQ你可以修改所附的CZE序来做q些试验?/p>

  八、ȝ

  session机制本nq不复杂Q然而其实现和配|上的灵zL却使得具体情况复杂多变。这也要求我们不能把仅仅某一ơ的l验或者某一个浏览器Q服务器的经验当作普遍适用的经验,而是始终需要具体情况具体分析?/p>

batistuta 2006-11-29 11:22 发表评论
]]>
Subversion使用手记http://www.aygfsteel.com/batistuta/articles/84012.htmlbatistutabatistutaTue, 28 Nov 2006 04:20:00 GMThttp://www.aygfsteel.com/batistuta/articles/84012.htmlhttp://www.aygfsteel.com/batistuta/comments/84012.htmlhttp://www.aygfsteel.com/batistuta/articles/84012.html#Feedback0http://www.aygfsteel.com/batistuta/comments/commentRss/84012.htmlhttp://www.aygfsteel.com/batistuta/services/trackbacks/84012.html一直以来对于自q目都是使用CVSq行理Q听说Subversion很久?jin),但是都没有时间去试。想x间都是省出来的,于是军_Q一天学一点,不多Q积累成沛_?br />  Subversion和CVS相比Q除?jin)包含?jin)CVS的全部特性之外,也加入了(jin)新的理念?br />                                    新理?br />  1、\径、改名、以?qing)文件meta-data也可q入版本控制范围?br />  ~少q些Ҏ(gu)是CVS被抱怨最多的斚w之一Qsubversion不止Ҏ(gu)件内容和文g存放位置加入控制Q也对目录,拯Q重命名操作加入版本控制。它也允许文?目录的相兛_数据meta-data和文?目录本n一赯版本控制hQƈ提供一U机制对文g的执行权限进行控制?br />  2、Commit动作真正成ؓ(f)原子U的操作?jin)?br />直到整个commit动作都成功前不会(x)有Q何部分的commit?x)生效。版本修订号只是预确认,而不是对文g预确认?译不出?-_-;)日志信息绑定到修订信息Q而不是象CVS那样冗余的存储下来?br /> 3、提供Apache|络服务器选项Q支持WebDAV/DeltaV协议?br />Subversion可以使用Zhttp协议的WebDAV/DeltaV协议q行|络通讯Qƈ由Apache服务器提供源码仓库方的网l浏览服务。这为Subversion提供?jin)比CVS更好的协同工作能力,q提供了(jin)各式各样的自q关键Ҏ(gu):(x)授权Q基于\径的授权Q线性压~,以及(qing)基本源码仓库览?br />4、独立服务器选项
Subversion也能提供独立服务器选项Q用自定的协议Q不是每个h都想q行Apache2.xQ独立服务器可以作ؓ(f)pȝ的inetd服务q行Qƈ提供基本的授权。它也能使用sshq行加密?br /> 5、徏?nobr>分支和标{操作成Z耗时的操作?br />q些动作没理p时Q所以我们不再让它们耗时?br />6、分支与标签的实现都是基于底层的拯操作Q一个拷贝占用一块固定大的I间。Q何拷贝都可以作ؓ(f)一份标{;假如你开始对某个版本的拷贝进行commit动作Q那它也成Z个分支?q与CVS?分支节点做标{?方式不同)
7、天然的client/serverl构Q层ơ化库设计?br />Subversion从设计之初即采用client/server机构Q因此避免了(jin)困扰CVS?jin)许久的一些维护性难题?br />代码被构Zؓ(f)一l带有详l接口说明的模块Q用以方便的由其他应用程序进行调用?br />8、Client/server协议向双方发送对比差异?br />|络协议利用宽带有效地发送对比差异给客户端和服务器端双方? CVS只是 server->client,?没有client->server )
 9、资源消耗与数据改变的大成正比Q而不是与数据本n大小成正比一般来_(d)一Subversion操作所需旉与操作最l变化的大小成正比。而不是与操作所触及(qing)的整个项目的大小成正比,q是Subversion源代码仓库模型的一个特性?br /> 10、有效的处理二进制文?br />Subversion对于二进制文件和文本文g的处理同h效,因ؓ(f)subversion使用一U二q制差异比较法来增量存储那些连l的修订本?br /> 11、易于语法分析的输出?br />所有Subversion命o(h)行客L(fng)的输出都是仔l设计的Q可LZh所理解Q也适于E序自动解析。可q行脚本语言处理是下一步优先考虑的特性?br /> 好了(jin)Q开始用吧?br />Subversion到目前的安装已经非常单了(jin)。到Subversion|站下蝲Windows下的安装文gQ简单的步骤可以完成安装,而且安装E序已经自动注册PathQ直接在命o(h)行模式就可以使用?jin)?br />  首先初始化RepositoryQ输入命?
 svnadmin create D:\TestRepository\
然后Q把现有的项目的目录l构以及(qing)文g导入到Repository中:(x)
 svn import D:\Projects\Project1 file:///D:\TestRepository\Project1 -m “初始化?br /> 用启动服?br /> svnserve -d -r D:\TestRepository\
 客户端Checkout
 svn checkout svn://L?Project1?? (卌取Project1的项?
 以上都是很简单的命o(h)。而且上面只用C(jin)一U服务模式,Apache的还在尝试中?br /> 目前只用C(jin)Subversion的基本功能,已l感觉不错了(jin)Q觉得入门很LQ帮助文档也比CVS要好的多?br /> Subversion也有囑Ş的客L(fng)Q可以在 TortoiseSVN 扑ֈ?br /> Subversion也VS.Net的插Ӟ可以在AnkhSVN 扑ֈ?br /> TortoiseSVN怿不错Q因Z前用q它的另一个For CVS的工P可以和浏览器l合在一P非常方便和美观?br />服务
    Subversionh两种服务模式Q一个是作ؓ(f)Apache的模块,另一个是自定义协议的Subserve服务。作为Apache的模块,客户端可以通过WebDAV/DeltaV协议讉KRepositoryQ而用Subserve则?br />Subversion的自定义协议?br />下表是两U服务模式的比较Q?/p>

功能

 

Apache + mod_dav_sub

Svnserve

验证方式

ZHTTPS?span lang="EN-US">X.509?span lang="EN-US">LDAP?span lang="EN-US">NTLM或其?span lang="EN-US">Apache支持的验?span lang="EN-US">

CRAM-MD5 或?span lang="EN-US">SSH

用户帐户理

U有的用h?span lang="EN-US">

U有的用h件或已有的系l帐?span lang="EN-US">

授权理

blanket read/write access 或单一目录的访问控?span lang="EN-US">

blanket read/write access

加密

可选的SSL

可选的SSH隧道

交互?span lang="EN-US">

可通过支持WebDAV的客L(fng)讉K

无交互?span lang="EN-US">

Web 讉K

有限的内|支持,或通过W三方的工具Q例?span lang="EN-US">ViewCVS

通过W三方的支持Q如ViewCVS

速度

E慢

E快

初始安装

E复?span lang="EN-US">

相当?span lang="EN-US">


                                   启动svnserve服务
svnserve 是一个轻量的服务, 使用自定义的协议通过TCP/IP?nobr>客户端通讯?br />客户端通过?svn:// 或?svn+ssh:// 开始的URL讉Ksvnserve服务器?br />启动服务?br />端口监控QinetdQ模?br />如果你打用端口监控来启动处理客L(fng)讉Kh的进E,你可以通过传入参数-i来启动:(x)
svnserve -i
当?i参数启动服务的时候,svnserve通过stdin和stdout用自定义协议和客L(fng)
通讯。同时服务侦?690端口?br />独立端口监控q程
使用参数-d启动服务作ؓ(f)一个独立的端口监控q程?br />svnserve -d
当运行svnserve在独立端口监控模式时Q你可以使用--listen-port=?-listen-host=参数来自定义需要的端口和主机名U。当前模式默认的端口?690?br />当然Q也有第三种Ҏ(gu)启动svnserveQ也是使用“隧道模式”,使用-t参数启动服务。这个模式要求远E服务程序,如RSH或SSHQ已l成功验证用Pq且使用已经校验的用户启动一个属于该用户的svnserveq程。当使用该模式提供服务时Q要认启动的用户帐户具备对Repository的读/写权限?br />讄目目录
当svnserve开始运行时Q它?yu)?x)暴露所有的Repository到网l上。不q,当客L(fng)需要获取一个Repository的内Ҏ(gu)Q需要指定Reopsitory的绝?nobr>路径。例如:(x)一个Repository攑֜文g路径
C:/Project Repository/Project1
那么当客L(fng)讉KӞ需要指定绝对\径:(x)
svn://host/C:/Project Repository/Project1
所以,Z(jin)增加保密性,你可以用参?r指定需要暴露的Repository的\径,当用戯问时Q只需指定Repository的名U即可。例如上面的RepositoryQ当启动服务Ӟ使用如下的方法:(x)
svn -d -r C:/Project Repository
那么当客L(fng)讉KӞ则?br />svn://host/Project1
可以获取数据了(jin)?br />内置的验证和授权
当客L(fng)q接C个svnserveq程Ӟ下面的流E就?x)触发?x)
1、客户选择一个指定的RepositoryQ?br />2、服务处理Repository的配|文?conf/svnserve.conf文gQƈ且开始执行在其中定义的所有验证和授权{略Q?br />3、依赖与情Ş和授权策略:(x)
a)客户端也许允许匿名访问而不需要验证,或?br />b)客户但也?dng)R要在M时候被要求验证Q或?br />c)假如处于"隧道模式"中,客户端将声明自己已经可以被外部验证?br />很显?dng)如上所_(d)用户文g是一个名为svnserve.conf的,攑֜conf目录下的文g?br />现在我们来看看如何配|这个文Ӟ(x)
q个配置文g攄在Repository的目录中的conf目录下,它有两个节点Q?br />[general]
[users]
其中Q[general]的配|信息有Q?br />anon-access = read
auth-access = write
其中表示对于验证有效的以?qing)没通过验证的用户可以做什么事情。分别有read, write和none
[users]?nobr>标签的配|内Ҏ(gu)Q?br />USERNAME = PASSWORD
password-db = passwd
realm = My First Repository
其中表示Q用户名对应的密码是什么,或者指定一个存储用户名和密码的文g的相Ҏ(gu)l对路径以及(qing)指定?jin)Repository的验证领域。如果两个Repository有相同的验证领域Q那么它们应该有相同的密码数据库Q反之亦然。默认的领域是指向当前的Repository的\径,与服务器的Repository的根目录相关?/p>

batistuta 2006-11-28 12:20 发表评论
]]>
վ֩ģ壺 | ޵| | | ɽ| | | ˮ| ֶ| ƽ| ·| 㶫ʡ| ͺ| | | | | | | | | | | 㶫ʡ| ޵| ̨ʡ| | | | ԰| | | Т| | | ʮ| Ž| ̫| | | Ͽ|