??xml version="1.0" encoding="utf-8" standalone="yes"?>欧美国产综合视频,久久这里有精品,欧美一区二区大片http://www.aygfsteel.com/yqin/category/45114.htmlzh-cnWed, 11 Aug 2010 16:07:30 GMTWed, 11 Aug 2010 16:07:30 GMT60session详解http://www.aygfsteel.com/yqin/articles/328302.htmlp?qz?/dc:creator>p?qz?/author>Mon, 09 Aug 2010 03:48:00 GMThttp://www.aygfsteel.com/yqin/articles/328302.htmlhttp://www.aygfsteel.com/yqin/comments/328302.htmlhttp://www.aygfsteel.com/yqin/articles/328302.html#Feedback0http://www.aygfsteel.com/yqin/comments/commentRss/328302.htmlhttp://www.aygfsteel.com/yqin/services/trackbacks/328302.html
一、术语session

在我的经验里Qsessionq个词被滥用的程度大概仅ơ于transactionQ更加有的是transaction与session在某些语境下的含义是相同的?

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

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

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

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

    在本文中Q用中?#8220;览器会(x)话期?#8221;来表辑֐义①Q?#8220;session机制”来表辑֐义④Q?#8220;session”表达含义⑤,使用具体?#8220;HttpSession”来表辑֐义⑥

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

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

    让我们用几个例子来描qC下cookie和session机制之间的区别与联系。笔者曾l常ȝ一家咖啡店有喝5杯咖啡免费赠一杯咖啡的优惠Q然而一ơ性消?杯咖啡的Z(x)微乎其微Q这时就需要某U方式来U录某位֮的消Ҏ(gu)量。想象一下其实也无外乎下面的几种Ҏ(gu)Q?、该店的店员很厉宻I能记住每位顾客的消费数量Q只要顾客一走进咖啡店,店员q道该怎么对待了。这U做法就是协议本w支持状态?/p>

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

    3、发l顾客一张会(x)员卡Q除了卡号之外什么信息也不纪录,每次消费Ӟ如果֮出示该卡片,则店员在店里的纪录本上找到这个卡号对应的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)员?#8221;如何分发Q?#8220;?x)员?#8221;的内容;以及(qing)客户如何使用“?x)员?#8221;?/p>

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

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

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

    如果不设|过期时_(d)则表C个cookie的生命期为浏览器?x)话期间Q只要关闭浏览器H口Qcookie消׃。这U生命期为浏览器?x)话期?cookie被称Z(x)话cookie.?x)话cookie一般不存储在硬盘上而是保存在内存里Q当然这U行为ƈ不是规范规定的。如果设|了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的响应头的例子HTTP/1.1 302 FoundLocationQ?nbsp;http://www.google.com/intl/zh-CN/Set-CookieQ?PREF=ID=0565f77e132de138QNW=1QTM=1098082649QLM=1098082649QS=KaeaCFPo49RiA_d8Q?expires=SunQ?17-Jan-2038 19Q?4Q?7 GMTQ?path=/Q?domain=.google.comContent-TypeQ?text/html

    q是使用HTTPLookq个HTTP Sniffer软g来俘L(fng)HTTP通讯U录的一部分

    览器在再次讉Kgoolge的资源时自动向外发送cookie

    用Firefox可以很容易的观察现有的cookie的g用HTTPLook配合F(tun)irefox可以很容易的理解cookie的工作原理?/p>

    IE也可以设|在接受cookie前询?/p>

    四、理解session机制

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

    当程序需要ؓ(f)某个客户端的h创徏一个session的时候,服务器首先检查这个客L(fng)的请求里是否已包含了一个session标识 - UCؓ(f) session idQ如果已包含一个session id则说明以前已lؓ(f)此客L(fng)创徏qsessionQ服务器按照session id把这?session索出来用(如果索不刎ͼ可能?x)新Z个)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的名字都是类gSEEESIONIDQ而。比如weblogic对于web应用E序生成的cookieQJSESSIONID= ByOK3vjFD75aPnrF7C2HmdnV6QZcEbzWoWiBYEnLerjQ99zWpBngQ?145788764Q它的名字就?JSESSIONID.

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

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

    另一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="ByOK3vjFD75aPnrF7C2HmdnV6QZcEbzWoWiBYEnLerjQ99zWpBngQ?145788764"><input type="text"></form>

    q种技术现在已较少应用Q笔者接触过的很古老的iPlanet6QSunONE应用服务器的前nQ就使用了这U技术?/p>

    实际上这U技术可以简单的用对action应用URL重写来代ѝ?/p>

    在谈论session机制的时候,常常听到q样一U误?#8220;只要关闭览器,session消׃”。其实可以想象一下会(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消׃Q再ơ连接服务器时也无法找到原来的session.如果服务器设|的cookie被保存到盘上,或者用某U手D|写浏览器发出的HTTPh_(d)把原来的session id发送给服务器,则再ơ打开览器仍然能够找到原来的session.

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

    五、理解javax.servlet.http.HttpSession

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

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

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

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

    cookie生存旉的设|则?x)媄响浏览器生成的cookie是否是一个会(x)话cookie.默认是用会(x)话cookie.有兴的可以用它来试验我们在W四节里提到的那个误解?/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.getSessionQtrueQ这L(fng)语句时才被创建,注意如果JSP没有昄的?<% @page session="false"%> 关闭sessionQ则JSP文g在编译成Servlet时将?x)自动加上这样一条语?HttpSession session = HttpServletRequest.getSessionQtrueQ;q也是JSP中隐含的 session对象的来历?/p>

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

    2、session何时被删除综合前面的讨论Qsession在下列情况下被删除a.E序调用HttpSession.invalidateQ)Q或b.距离上一ơ收到客L(fng)发送的session id旉间隔过了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.

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

    6、如何才能正的应付客户端禁止cookie的可能性对所有的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)对这个问题的{案有媄响?/p>

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

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

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

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

    七、跨应用E序的session׃n

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

    然而按照Servlet规范Qsession的作用范围应该仅仅限于当前应用程序下Q不同的应用E序之间是不能够互相讉KҎ(gu)的session的。各个应用服务器从实际效果上都遵守了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也可以是不同的?/p>

    Ҏ(gu)q个Ҏ(gu),我们可以推测Tomcat中session的内存结构大致如下?/p>

    W者以前用q的iPlanet也采用的是同L(fng)方式Q估计SunONE与iPlanet之间不会(x)有太大的差别。对于这U方式的服务器,解决的思\很简单,实际实行h也不难。要么让所有的应用E序׃n一个session idQ要么让应用E序能够获得其他应用E序的session id.

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

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

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

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

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

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

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

    应用E序A context.setAttributeQ?appA"Q?sessionQ;

    应用E序B contextA = context.getContextQ?/appA"Q;HttpSession sessionA = QHttpSessionQcontextA.getAttributeQ?appA"Q;

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

    那么Weblogic ServerZ么要把所有的应用E序的cookie路径都设?呢?原来是ؓ(f)了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>

    摘要Q虽然session机制在web应用E序中被采用已经很长旉了,但是仍然有很多h不清楚session机制的本质,以至不能正确的应用这一技术。本文将详细讨论session的工作机制ƈ且对在Java web application中应用session机制时常见的问题作出解答?/p>




]]>
深刻理解Java中的堆和?/title><link>http://www.aygfsteel.com/yqin/articles/324921.html</link><dc:creator>p?qz?/dc:creator><author>p?qz?/author><pubDate>Wed, 30 Jun 2010 13:06:00 GMT</pubDate><guid>http://www.aygfsteel.com/yqin/articles/324921.html</guid><wfw:comment>http://www.aygfsteel.com/yqin/comments/324921.html</wfw:comment><comments>http://www.aygfsteel.com/yqin/articles/324921.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.aygfsteel.com/yqin/comments/commentRss/324921.html</wfw:commentRss><trackback:ping>http://www.aygfsteel.com/yqin/services/trackbacks/324921.html</trackback:ping><description><![CDATA[<span style="font-family: 宋体; font-size: 14px; line-height: 25px; "> <p style="margin-top: 10px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; word-wrap: break-word; ">   栈与堆都?a target="_blank" style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; word-wrap: break-word; font-size: 14px; font-family: 宋体; text-decoration: none; color: #0000ff; line-height: 22px; ">Java</a>用来在RAM中存放数据的地方。与<a target="_blank" style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; word-wrap: break-word; font-size: 14px; font-family: 宋体; text-decoration: none; color: #0000ff; line-height: 22px; ">C++</a>不同Q?a target="_blank" style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; word-wrap: break-word; font-size: 14px; font-family: 宋体; text-decoration: none; color: #0000ff; line-height: 22px; ">Java</a>自动理栈和堆,E序员不能直接地讄栈或堆?/p> <p style="margin-top: 10px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; word-wrap: break-word; ">  Java的堆是一个运行时数据?cȝ对象从中分配I间。这些对象通过new、newarray、anewarray?multianewarray{指令徏立,它们不需要程序代码来昑ּ的释放。堆是由垃圾回收来负责的Q堆的优势是可以动态地分配内存大小Q生存期也不必事 先告诉编译器Q因为它是在q行时动态分配内存的QJava的垃圾收集器?x)自动收走这些不再用的数据。但~点是,׃要在q行时动态分配内存,存取速度?慢?/p> <p style="margin-top: 10px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; word-wrap: break-word; ">  栈的优势是,存取速度比堆要快Q仅ơ于寄存器,栈数据可以共享。但~点是,存在栈中的数据大与生存期必L定的,~Z灉|性。栈中主要存放一些基本类 型的变量(,int, short, long, byte, float, double, boolean, char)和对象句柄?/p> <p style="margin-top: 10px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; word-wrap: break-word; ">  栈有一个很重要的特D性,是存在栈中的数据可以共享。假设我们同时定义:(x)</p> <p style="margin-top: 10px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; word-wrap: break-word; ">  int a = 3;</p> <p style="margin-top: 10px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; word-wrap: break-word; ">  int b = 3;</p> <p style="margin-top: 10px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; word-wrap: break-word; ">  ~译器先处理int a = 3;首先它会(x)在栈中创Z个变量ؓ(f)a的引用,然后查找栈中是否?q个|如果没找刎ͼ将3存放q来Q然后将a指向3。接着处理int b = 3;在创建完b的引用变量后Q因为在栈中已经?q个|便将b直接指向3。这P出Ca与b同时均指?的情c(din)?/p> <p style="margin-top: 10px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; word-wrap: break-word; ">  q时Q如果再令a=4;那么~译器会(x)重新搜烦栈中是否?|如果没有Q则?存放q来Qƈ令a指向4;如果已经有了Q则直接a指向q个?址。因此a值的改变不会(x)影响到b的倹{?/p> <p style="margin-top: 10px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; word-wrap: break-word; ">  要注意这U数据的׃n与两个对象的引用同时指向一个对象的q种׃n是不同的Q因U情况a的修改ƈ不会(x)影响到b, 它是q译器完成的,它有利于节省I间。而一个对象引用变量修改了q个对象的内部状态,?x)媄响到另一个对象引用变量?/p> <p style="margin-top: 10px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; word-wrap: break-word; ">  String是一个特D的包装cL据。可以用Q?/p> <p style="margin-top: 10px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; word-wrap: break-word; ">  String str = new String("abc");</p> <p style="margin-top: 10px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; word-wrap: break-word; ">  String str = "abc";</p> <p style="margin-top: 10px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; word-wrap: break-word; ">  两种的Ş式来创徏Q第一U是用new()来新建对象的Q它?x)在存放于堆中。每调用一ơ就?x)创Z个新的对象?/p> <p style="margin-top: 10px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; word-wrap: break-word; ">  而第二种是先在栈中创Z个对Stringcȝ对象引用变量strQ然后查找栈中有没有存放"abc"Q如果没有,则将"abc"存放q栈Qƈ 令str指向”abc”Q如果已l有”abc” 则直接o(h)str指向“abc”?/p> <p style="margin-top: 10px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; word-wrap: break-word; ">  比较c里面的数值是否相{时Q用equals()Ҏ(gu);?a target="_blank" style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; word-wrap: break-word; font-size: 14px; font-family: 宋体; text-decoration: none; color: #0000ff; line-height: 22px; ">试</a>两个包装cȝ引用是否指向同一个对象时Q用==Q下面用例子说明上面的理论?/p> <p style="margin-top: 10px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; word-wrap: break-word; ">  String str1 = "abc";</p> <p style="margin-top: 10px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; word-wrap: break-word; ">  String str2 = "abc";</p> <p style="margin-top: 10px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; word-wrap: break-word; ">  System.out.println(str1==str2); //true</p> <p style="margin-top: 10px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; word-wrap: break-word; ">  可以看出str1和str2是指向同一个对象的?/p> <p style="margin-top: 10px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; word-wrap: break-word; ">  String str1 =new String ("abc");</p> <p style="margin-top: 10px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; word-wrap: break-word; ">  String str2 =new String  ("abc");</p> <p style="margin-top: 10px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; word-wrap: break-word; ">  System.out.println(str1==str2); // false</p> <p style="margin-top: 10px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; word-wrap: break-word; ">  用new的方式是生成?同的对象。每一ơ生成一个?/p> <p style="margin-top: 10px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; word-wrap: break-word; ">  因此用第一U方式创建多?#8221;abc”字符?在内存中其实只存在一个对象而已. q种写法有利与节省内存空? 同时它可以在一定程度上提高E序的运行速度Q因为JVM?x)自动根据栈中数据的实际情况来决定是否有必要创徏新对象。而对于String str = new String("abc");的代码,则一概在堆中创徏新对象,而不其字符串值是否相{,是否有必要创建新对象Q从而加重了E序的负担?/p> <p style="margin-top: 10px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; word-wrap: break-word; ">  另一斚w, 要注? 我们在用诸如String str = "abc";的格式定义类ӞL惛_然地认ؓ(f)Q创ZStringcȝ对象str。担心陷?对象可能q没有被创徏!而可能只是指向一个先前已l创建的 对象。只有通过new()Ҏ(gu)才能保证每次都创Z个新的对象?/p> <p style="margin-top: 10px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; word-wrap: break-word; ">  ׃Stringcȝimmutable性质Q当String变量需要经常变换其值时Q应该考虑使用StringBufferc,以提高程序效 率?/p> <p style="margin-top: 10px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; word-wrap: break-word; ">  <strong style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; word-wrap: break-word; ">甌后系l的响应</strong></p> <p style="margin-top: 10px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; word-wrap: break-word; ">  栈:(x)只要栈的剩余I间大于所甌I间Q系l将为程序提供内存,否则报异常提示栈溢出?/p> <p style="margin-top: 10px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; word-wrap: break-word; ">  堆:(x) 首先应该知道操作pȝ有一个记录空闲内存地址的链表,当系l收到程序的甌Ӟ?x)遍历该链表Q寻扄一个空间大于所甌I间的堆l点Q然后将该结点从I闲 l点链表中删除,q将该结点的I间分配l程序,另外Q对于大多数pȝQ会(x)在这块内存空间中的首地址处记录本ơ分配的大小Q这P代码中的delete语句 才能正确的释放本内存I间。另外,׃扑ֈ的堆l点的大不一定正好等于申L(fng)大小Q系l会(x)自动的将多余的那部分重新攑օI闲链表中?/p> <p style="margin-top: 10px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; word-wrap: break-word; ">  <strong style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; word-wrap: break-word; ">甌大小的限?/strong></p> <p style="margin-top: 10px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; word-wrap: break-word; ">  栈:(x)?a target="_blank" style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; word-wrap: break-word; font-size: 14px; font-family: 宋体; text-decoration: none; color: #0000ff; line-height: 22px; ">Windows</a>?栈是向低地址扩展的数据结构,是一块连l的内存的区域。这句话的意思是栈顶的地址和栈的最大容量是pȝ预先规定好的Q?在WINDOWS下,栈的大小?M(也可能是1MQ它是一个编译时q定的常数)Q如果申L(fng)I间过栈的剩余I间Ӟ提Coverflow。因此, 能从栈获得的I间较小?/p> <p style="margin-top: 10px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; word-wrap: break-word; ">  堆:(x)堆是向高地址扩展的数据结构,是不q箋的内存区域。这是由于系l是用链表来<a target="_blank" style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; word-wrap: break-word; font-size: 14px; font-family: 宋体; text-decoration: none; color: #0000ff; line-height: 22px; ">存储</a>的空闲内存地址的,自然是不q箋的,而链表的遍历方向是由?地址向高地址。堆的大受限于计算机系l中有效的虚拟内存。由此可见,堆获得的I间比较灉|Q也比较大?/p> <p style="margin-top: 10px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; word-wrap: break-word; ">  <strong style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; word-wrap: break-word; ">甌效率的比较:(x)</strong></p> <p style="margin-top: 10px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; word-wrap: break-word; ">  栈由pȝ自动分配Q速度较快。但E序员是无法控制的?/p> <p style="margin-top: 10px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; word-wrap: break-word; ">  堆是由new分配的内存,一般速度比较慢,而且Ҏ(gu)产生内存片,不过用v来最方便.</p> <p style="margin-top: 10px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; word-wrap: break-word; ">  另外Q在WINDOWS下,最好的方式是用VirtualAlloc分配内存Q他不是在堆Q也不是在栈是直接在q程的地址I间中保留一快内存, 虽然用v来最不方ѝ但是速度快,也最灉|?/p> <p style="margin-top: 10px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; word-wrap: break-word; ">  <strong style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; word-wrap: break-word; ">堆和栈中?a target="_blank" style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; word-wrap: break-word; font-size: 14px; font-family: 宋体; text-decoration: none; color: #0000ff; line-height: 22px; ">存储</a>内容</strong></p> <p style="margin-top: 10px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; word-wrap: break-word; ">  栈:(x)在函数调用时Q第一个进栈的是主函数中后的下一条指?函数调用语句的下一条可执行语句)的地址Q然后是函数的各个参敎ͼ在大多数的C~译 器中Q参数是由右往左入栈的Q然后是函数中的局部变量。注意静态变量是不入栈的?/p> <p style="margin-top: 10px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; word-wrap: break-word; ">  当本ơ函数调用结束后Q局部变量先出栈Q然后是参数Q最后栈指针指向最开始存的地址Q也是dC的下一条指令,E序p点l运行?/p> <p style="margin-top: 10px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; word-wrap: break-word; ">  堆:(x)一般是在堆的头部用一个字节存攑֠的大。堆中的具体内容有程序员安排?/p> <p style="margin-top: 10px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; word-wrap: break-word; ">  <strong style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; word-wrap: break-word; ">存取效率的比?/strong></p> <p style="margin-top: 10px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; word-wrap: break-word; ">  char s1[] = "aaaaaaaaaaaaaaa";</p> <p style="margin-top: 10px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; word-wrap: break-word; ">  char *s2 = "bbbbbbbbbbbbbbbbb";</p> <p style="margin-top: 10px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; word-wrap: break-word; ">  aaaaaaaaaaa是在q行时刻赋值的;</p> <p style="margin-top: 10px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; word-wrap: break-word; ">  而bbbbbbbbbbb是在~译时就定?</p> <p style="margin-top: 10px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; word-wrap: break-word; ">  但是Q在以后的存取中Q在栈上的数l比指针所指向的字W串(例如?快?/p> <p style="margin-top: 10px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; word-wrap: break-word; ">  比如Q?/p> <p style="margin-top: 10px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; word-wrap: break-word; ">  void main()</p> <p style="margin-top: 10px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; word-wrap: break-word; ">  {</p> <p style="margin-top: 10px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; word-wrap: break-word; ">  char a = 1;</p> <p style="margin-top: 10px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; word-wrap: break-word; ">  char c[] =  "1234567890";</p> <p style="margin-top: 10px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; word-wrap: break-word; ">  char *p ="1234567890";</p> <p style="margin-top: 10px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; word-wrap: break-word; ">  a = c[1];</p> <p style="margin-top: 10px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; word-wrap: break-word; ">  a =  p[1];</p> <p style="margin-top: 10px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; word-wrap: break-word; ">  return;</p> <p style="margin-top: 10px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; word-wrap: break-word; ">  }</p> <p style="margin-top: 10px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; word-wrap: break-word; ">  对应的汇~代?/p> <p style="margin-top: 10px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; word-wrap: break-word; ">  10: a = c[1];</p> <p style="margin-top: 10px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; word-wrap: break-word; ">  00401067 8A 4D F1 mov cl,byte ptr [ebp-0Fh]</p> <p style="margin-top: 10px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; word-wrap: break-word; ">  0040106A 88 4D FC mov byte ptr [ebp-4],cl</p> <p style="margin-top: 10px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; word-wrap: break-word; ">  11: a = p[1];</p> <p style="margin-top: 10px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; word-wrap: break-word; ">  0040106D 8B 55 EC mov edx,dword ptr [ebp-14h]</p> <p style="margin-top: 10px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; word-wrap: break-word; ">  00401070 8A 42 01  mov al,byte ptr [edx+1]</p> <p style="margin-top: 10px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; word-wrap: break-word; ">  00401073 88 45 FC mov byte ptr [ebp-4],al</p> <p style="margin-top: 10px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; word-wrap: break-word; ">  W一U在d时直接就把字W串中的元素d寄存器cl中,而第二种则要先把指针D到edx中,在根?/p> <p style="margin-top: 10px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; word-wrap: break-word; ">  edxd字符Q显然慢了?/p> <p style="margin-top: 10px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; word-wrap: break-word; ">  <strong style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; word-wrap: break-word; ">结Q?/strong></p> <p style="margin-top: 10px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; word-wrap: break-word; ">  堆和栈的区别可以用如下的比喻来看出:(x)</p> <p style="margin-top: 10px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; word-wrap: break-word; ">  使用栈就象我们去饭馆里吃饭,只管点菜(发出甌)、付钱、和?使用)Q吃׃pQ不必理?x)切菜、洗菜等准备工作和洗、刷锅等扫尾工作Q?他的好处是快P但是自由度小?/p> </span> <img src ="http://www.aygfsteel.com/yqin/aggbug/324921.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.aygfsteel.com/yqin/" target="_blank">p?qz?/a> 2010-06-30 21:06 <a href="http://www.aygfsteel.com/yqin/articles/324921.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>HTTP中的重定向和h转发的区?/title><link>http://www.aygfsteel.com/yqin/articles/322952.html</link><dc:creator>p?qz?/dc:creator><author>p?qz?/author><pubDate>Mon, 07 Jun 2010 02:56:00 GMT</pubDate><guid>http://www.aygfsteel.com/yqin/articles/322952.html</guid><wfw:comment>http://www.aygfsteel.com/yqin/comments/322952.html</wfw:comment><comments>http://www.aygfsteel.com/yqin/articles/322952.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.aygfsteel.com/yqin/comments/commentRss/322952.html</wfw:commentRss><trackback:ping>http://www.aygfsteel.com/yqin/services/trackbacks/322952.html</trackback:ping><description><![CDATA[<p><strong><span style="font-size:14.0pt;font-family:宋体;Times New Roman";Times New Roman"">一、调用方?/span></strong></p> <p><span style="font-family:宋体;Times New Roman";Times New Roman"">我们知道Q在</span>servlet<span style="font-family:宋体;Times New Roman";Times New Roman"">中调用{发、重定向的语句如下:(x)</span></p> <p><span>request.getRequestDispatcher("new.jsp").forward(request, response);   //</span><span style="font-family:宋体;Times New Roman";Times New Roman"">转发?/span>new.jsp</p> <p>response.sendRedirect("new.jsp");   //<span style="font-family:宋体;Times New Roman";Times New Roman"">重定向到</span>new.jsp</p> <p><span style="font-family:宋体;Times New Roman";Times New Roman"">?/span>jsp<span style="font-family:宋体;Times New Roman";Times New Roman"">面中你也会(x)看到通过下面的方式实现{发:(x)</span></p> <p><span><jsp:forward page="apage.jsp" /></span></p> <p><span style="font-family:宋体;Times New Roman";Times New Roman"">当然也可以在</span>jsp<span style="font-family:宋体;Times New Roman";Times New Roman"">面中实现重定向Q?/span></p> <p><span><%response.sendRedirect("new.jsp"); %> //</span><span style="font-family: 宋体;Times New Roman";Times New Roman"">重定向到</span>new.jsp</p> <p><strong><span style="font-size:14.0pt;font-family:宋体;Times New Roman";Times New Roman"">二、本质区?/span></strong></p> <p><strong><span style="font-family:宋体;Times New Roman";Times New Roman"">解释一</span></strong></p> <p><span style="font-family:宋体;Times New Roman";Times New Roman"">一句话Q?span style="color:red">转发是服务器行ؓ(f)Q重定向是客L(fng)行ؓ(f)?/span>Z么这栯呢,q就要看两个动作的工作流E:(x)</span></p> <p><span style="font-family:宋体;Times New Roman";Times New Roman";color:red">转发q程Q?/span><span style="font-family:宋体;Times New Roman";Times New Roman"">客户览器发?/span>http<span style="font-family:宋体;Times New Roman";Times New Roman"">h——?/span>web<span style="font-family:宋体;Times New Roman";Times New Roman"">服务器接受此h——》调用内部的一个方法在容器内部完成h处理和{发动作——》将目标资源发送给客户Q在q里Q{发的路径必须是同一?/span>web<span style="font-family:宋体;Times New Roman";Times New Roman"">容器下的</span>url<span style="font-family:宋体;Times New Roman";Times New Roman"">Q其不能转向到其他的</span>web<span style="font-family:宋体;Times New Roman";Times New Roman"">路径上去Q中间传递的是自q容器内的</span>request<span style="font-family:宋体;Times New Roman";Times New Roman"">。在客户览器\径栏昄的仍然是其第一ơ访问的路径Q也是说客h感觉不到服务器做了{发的。{发行为是览器只做了一ơ访问请求?/span></p> <p><span style="font-family:宋体;Times New Roman";Times New Roman";color:red">重定向过E:(x)</span><span style="font-family:宋体;Times New Roman";Times New Roman"">客户览器发?/span>http<span style="font-family:宋体;Times New Roman";Times New Roman"">h——?/span>web<span style="font-family:宋体;Times New Roman";Times New Roman"">服务器接受后发?/span>302<span style="font-family:宋体;Times New Roman";Times New Roman"">状态码响应?qing)对应新?/span>location<span style="font-family:宋体;Times New Roman";Times New Roman"">l客h览器——》客h览器发现?/span>302<span style="font-family:宋体;Times New Roman";Times New Roman"">响应Q则<strong>自动</strong>再发送一个新?/span>http<span style="font-family:宋体;Times New Roman";Times New Roman"">hQ请?/span>url<span style="font-family:宋体;Times New Roman";Times New Roman"">是新?/span>location<span style="font-family:宋体;Times New Roman";Times New Roman"">地址——》服务器Ҏ(gu)此请求寻找资源ƈ发送给客户。在q里</span>location<span style="font-family:宋体;Times New Roman";Times New Roman"">可以重定向到L</span>URL<span style="font-family:宋体;Times New Roman";Times New Roman"">Q既然是览器重新发ZhQ则没有什?/span>request<span style="font-family:宋体;Times New Roman";Times New Roman"">传递的概念了。在客户览器\径栏昄的是光定向的\径,客户可以观察到地址的变化的。重定向行ؓ(f)是浏览器做了臛_两次的访问请求的?/span></p> <p><strong><span style="font-family:宋体;Times New Roman";Times New Roman"">解释?/span></strong></p> <p><span style="font-family:宋体;Times New Roman";Times New Roman"">重定向,其实是两?/span>request</p> <p><span style="font-family:宋体;Times New Roman";Times New Roman"">W一ơ,客户?/span>request   A,<span style="font-family:宋体;Times New Roman";Times New Roman"">服务器响应,q?/span>response<span style="font-family:宋体;Times New Roman";Times New Roman"">回来Q告诉浏览器Q你应该?/span>B<span style="font-family:宋体;Times New Roman";Times New Roman"">。这个时?/span>IE<span style="font-family:宋体;Times New Roman";Times New Roman"">可以看到地址变了Q而且历史的回退按钮也亮了。重定向可以讉K自己</span>web<span style="font-family:宋体;Times New Roman";Times New Roman"">应用以外的资源?span style="color:red">在重定向的过E中Q传输的信息?x)被丢失?/span></span></p> <p><span style="font-family:宋体;Times New Roman";Times New Roman"">例子Q?/span></p> <p style="text-indent:21.0pt">response.sendRedirect("loginsuccess.jsp");</p> <p><span style="font-family:宋体;Times New Roman";Times New Roman"">h转发是服务器内部把对一?/span>request/response<span style="font-family:宋体;Times New Roman";Times New Roman"">的处理权Q移交给另外一?/span></p> <p><span style="font-family:宋体;Times New Roman";Times New Roman"">对于客户端而言Q它只知道自己最早请求的那个</span>A<span style="font-family:宋体;Times New Roman";Times New Roman"">Q而不知道中间?/span>B<span style="font-family:宋体;Times New Roman";Times New Roman"">Q甚?/span>C<span style="font-family: 宋体;Times New Roman";Times New Roman"">?/span>D<span style="font-family:宋体;Times New Roman";Times New Roman"">?/span><span style="font-family:宋体;Times New Roman";Times New Roman";color:red">传输的信息不?x)丢失?/span></p> <p><span style="font-family:宋体;Times New Roman";Times New Roman"">例子Q?/span></p> <p><span>       RequestDispatcher dis=request.getRequestDispatcher(“loginsuccess.jsp”);</span></p> <p>       Dis.forward(request,response);</p> <p><strong><span style="font-family:宋体;Times New Roman";Times New Roman"">解释?/span></strong></p> <p><span style="font-family:宋体;Times New Roman";Times New Roman"">假设你去办理某个执照</span></p> <p><span style="font-family:宋体;Times New Roman";Times New Roman"">重定向:(x)你先M</span>A<span style="font-family:宋体;Times New Roman";Times New Roman"">局Q?/span>A<span style="font-family: 宋体;Times New Roman";Times New Roman"">局的h_(d)(x)“q个事情不归我们,?/span>B<span style="font-family:宋体;Times New Roman";Times New Roman"">局”Q然后,你就?/span>A<span style="font-family:宋体;Times New Roman";Times New Roman"">退了出来,自己乘RM</span>B<span style="font-family:宋体;Times New Roman";Times New Roman"">局?/span></p> <p><span style="font-family:宋体;Times New Roman";Times New Roman"">转发Q你先去?/span>A<span style="font-family:宋体;Times New Roman";Times New Roman"">局Q?/span>A<span style="font-family: 宋体;Times New Roman";Times New Roman"">局看了以后Q知道这个事情其实应?/span>B<span style="font-family:宋体;Times New Roman";Times New Roman"">局来管Q但是他没有把你退回来Q而是让你坐一?x)儿Q自己到后面办公室联pM</span>B<span style="font-family:宋体;Times New Roman";Times New Roman"">的hQ让他们办好后,送了q来?/span></p> <img src ="http://www.aygfsteel.com/yqin/aggbug/322952.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.aygfsteel.com/yqin/" target="_blank">p?qz?/a> 2010-06-07 10:56 <a href="http://www.aygfsteel.com/yqin/articles/322952.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Java 反射QReflectionQ?l典实用例子http://www.aygfsteel.com/yqin/articles/322164.htmlp?qz?/dc:creator>p?qz?/author>Fri, 28 May 2010 09:42:00 GMThttp://www.aygfsteel.com/yqin/articles/322164.htmlhttp://www.aygfsteel.com/yqin/comments/322164.htmlhttp://www.aygfsteel.com/yqin/articles/322164.html#Feedback0http://www.aygfsteel.com/yqin/comments/commentRss/322164.htmlhttp://www.aygfsteel.com/yqin/services/trackbacks/322164.html阅读全文

]]>
վ֩ģ壺 | | ũ| | | | | | | ʡ| ƽ| | н| | Ľ| | ͨ| | | | ¡| ˮ| | | ֻ| | | ˮ| | | | | | | | | Ϫ| | | | |