日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問(wèn) 生活随笔!

生活随笔

當(dāng)前位置: 首頁(yè) > 前端技术 > javascript >内容正文

javascript

Head First JSP---随笔四

發(fā)布時(shí)間:2025/3/15 javascript 12 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Head First JSP---随笔四 小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

會(huì)話狀態(tài)

Web服務(wù)器沒(méi)有短期記憶。在Servlet API中可以找到一種極其簡(jiǎn)單的解決方法。


會(huì)話管理

4.1 編寫(xiě)servlet代碼,將對(duì)象保存到一個(gè)會(huì)話對(duì)象中,以及從會(huì)話對(duì)象獲得對(duì)象。
4.2 給定一個(gè)場(chǎng)景,描述訪問(wèn)會(huì)話對(duì)象使用的API,解釋何時(shí)創(chuàng)建會(huì)話對(duì)象,并描述撤銷會(huì)話對(duì)象使用的機(jī)制,以及何時(shí)撤銷會(huì)話對(duì)象。
4.3 使用會(huì)話監(jiān)聽(tīng)者,編寫(xiě)代碼對(duì)會(huì)話的有關(guān)時(shí)間做出響應(yīng),包括向會(huì)話增加一個(gè)對(duì)象,以及會(huì)話對(duì)象從VM遷移到另一個(gè)VM。
4.4 給定一個(gè)場(chǎng)景,說(shuō)明Web容器可以采用哪些會(huì)話管理機(jī)制,如何使用cookie來(lái)管理會(huì)話,以及如何使用URL重寫(xiě)管理會(huì)話,并編寫(xiě)servlet代碼完成URL重寫(xiě)。


容器怎么知道客戶是誰(shuí)?

對(duì)容器而言,每個(gè)請(qǐng)求都來(lái)自于一個(gè)新的客戶

解決:客戶需要一個(gè)唯一的會(huì)話ID。容器會(huì)生成一個(gè)唯一的會(huì)話ID,并通過(guò)響應(yīng)把它返回給客戶。客戶在以后的每一個(gè)請(qǐng)求中發(fā)回這個(gè)會(huì)話ID給服務(wù)器。如下圖:


容器機(jī)會(huì)做cookie的所有工作

在響應(yīng)中發(fā)送一個(gè)會(huì)話cookie與從請(qǐng)求得到會(huì)話ID的代碼一樣,如下:

HttpSession session = request.getSession();

就這么簡(jiǎn)單。在你的服務(wù)方法中請(qǐng)求一個(gè)會(huì)話,余下的所有事情都會(huì)自動(dòng)完成。

自動(dòng)完成的事:

  • 建立新的HttpSession
  • 生成唯一的會(huì)話ID
  • 建立新的cookie對(duì)象
  • 會(huì)話ID與cookie關(guān)聯(lián)
  • 響應(yīng)中設(shè)置cookie(set-cookie首部下)
  • cookie的所有工作都在后臺(tái)進(jìn)行

怎么知道會(huì)話已經(jīng)存在,還是剛剛創(chuàng)建?

請(qǐng)求的無(wú)參方法getSession會(huì)返回一個(gè)會(huì)話,而不論是否已經(jīng)有一個(gè)會(huì)話。因?yàn)槲覀兛偰軓倪@個(gè)方法得到返回的一個(gè)HttpSession實(shí)例。所以,要知道會(huì)話是不是新創(chuàng)建的,只有去問(wèn)會(huì)話

HttpSession session = request.getSession();if(session.isNew()){//客戶還沒(méi)用過(guò)這個(gè)會(huì)話,或者說(shuō)是新創(chuàng)建的 }else{//客戶已經(jīng)使用過(guò)這個(gè)會(huì)話 }

這里指出:得到會(huì)話的方式不止request.getSession()一種


如果我只想要一個(gè)已經(jīng)有的會(huì)話呢?

某些情況下,servlet可能只想使用一個(gè)原來(lái)創(chuàng)建的會(huì)話。例如,讓結(jié)賬servlet再開(kāi)始一個(gè)新的會(huì)話可能就不太合適。

所以,針對(duì)這個(gè)目的,專門(mén)有一個(gè)重載的getSession(boolean)方法。

//傳遞一個(gè)false表示,這個(gè)方法會(huì)返回一個(gè)已經(jīng)有的會(huì)話,如果沒(méi)有與此客戶關(guān)聯(lián)的會(huì)話,則會(huì)返回null HttpSession session = request.getSession(false);if(session==null){//會(huì)話不存在,創(chuàng)建一個(gè)session = request.getSession(); }else{//會(huì)話以存在 }

比較上面2種獲取session的方法,它們其實(shí)是一樣的。除非你并不想創(chuàng)建一個(gè)session就可以直接用getSession(false),當(dāng)不存在一個(gè)session的時(shí)候,你判斷為空,并不去創(chuàng)建一個(gè)新的session。


如果不能用cookie

如果客戶禁用掉cookie,那么客戶就會(huì)忽略“Set-Cookie”響應(yīng)首部。這樣的話,那又該如何處理呢?(session的機(jī)制就是靠cookie實(shí)現(xiàn)的,所以cookie不能用就等于session不能用)

就算客戶不接受cookie,我們也能完成會(huì)話,但是必須稍微多做點(diǎn)工作。

解決:URL重寫(xiě)(一條后路),如下:
URL+;jsessionid=1234567

如圖:

還差最后一步:需要告訴響應(yīng)要對(duì)URL編碼,URL重寫(xiě)才能奏效

PrintWriter out = response.getWriter(); HttpSession session = request.getSession();//向這個(gè)"/BeerTest.do"這個(gè)URL增加額外的會(huì)話ID信息 out.println(response.encodeURL("/BeerTest.do"));

這里還有一個(gè)問(wèn)題,容器怎么知道客戶端cookie不能正常工作?
方法很簡(jiǎn)單:返回第一個(gè)響應(yīng)時(shí),它會(huì)同時(shí)嘗試cookie和URL重寫(xiě)這兩種方式。


使用sendRedirect()的URL重寫(xiě)

可能會(huì)有這種情況,你想把請(qǐng)求重定向到另外一個(gè)URL,但是還想使用一個(gè)會(huì)話。為此,有一個(gè)特殊的URL編碼方法:response.encodeRedirectURL("/BeerTest.do")。


會(huì)話注意點(diǎn)


URL重寫(xiě)要點(diǎn)

  • 在寫(xiě)至響應(yīng)的HTML中,URL重寫(xiě)會(huì)把會(huì)話ID增加到其中所有的URL的最后。(例如url;jsessionid=1234567)
  • 會(huì)話ID作為請(qǐng)求URL最后的“額外”信息再通過(guò)請(qǐng)求返回。
  • 如果客戶不接受cookie,URL重寫(xiě)會(huì)自動(dòng)發(fā)生,但是必須顯示的對(duì)所有URL編碼。
  • 要對(duì)一個(gè)URL編碼,需要調(diào)用response.encodeURL(String url)。
  • 沒(méi)有辦法對(duì)靜態(tài)頁(yè)面完成自動(dòng)的URL重寫(xiě),所以,如果你依賴于會(huì)話,就必須使用動(dòng)態(tài)生成的頁(yè)面。

  • 刪除會(huì)話

    由于客戶可能會(huì)因?yàn)楦鞣N原因?qū)е聲?huì)話結(jié)束,可是我們沒(méi)將Session銷毀,這個(gè)時(shí)候容器又如何知道什么時(shí)候能安全地撤銷一個(gè)會(huì)話?

    HttpSession接口的UML

    方法名作用一般用途
    getCreationTime()返回第一次創(chuàng)建會(huì)話的時(shí)間得出這個(gè)會(huì)話有多“老”。你可能想要把某些會(huì)話的壽命限制為一個(gè)固定的值。例如,你可能會(huì)說(shuō)“一旦登錄,就必須在10分鐘之內(nèi)完成這個(gè)表單”
    getLastAccesssedTime()返回容器最后一次得到包含這個(gè)會(huì)話ID的請(qǐng)求后過(guò)去了多長(zhǎng)時(shí)間(毫秒數(shù))得出客戶最后一次訪問(wèn)這個(gè)會(huì)話是什么時(shí)候。可以用這個(gè)方法來(lái)確定客戶是否已經(jīng)離開(kāi)很長(zhǎng)時(shí)間,這樣就可以像客戶發(fā)出一份email,詢問(wèn)他們是否還回來(lái)。或者可以調(diào)用invalidate()結(jié)束會(huì)話
    setMaxInactiveInterval()指定對(duì)于這個(gè)會(huì)話客戶請(qǐng)求的最大間隔時(shí)間(秒數(shù))如果已經(jīng)過(guò)去了指定的時(shí)間,而客戶未對(duì)這個(gè)會(huì)話做任何請(qǐng)求,就會(huì)導(dǎo)致會(huì)話被撤銷。可以用這個(gè)方法減少服務(wù)器中無(wú)用的會(huì)話
    getMaxInactiveInterval()返回對(duì)于這個(gè)會(huì)話客戶請(qǐng)求的最大時(shí)間間隔得出這個(gè)會(huì)話可以保持多長(zhǎng)時(shí)間不活動(dòng)當(dāng)仍“存活”。可以使用這個(gè)方法來(lái)判斷一個(gè)會(huì)話不活動(dòng)的客戶在會(huì)話撤銷之前還有多長(zhǎng)的“壽命”
    invalidate()結(jié)束會(huì)話。當(dāng)前存儲(chǔ)在這個(gè)會(huì)話中的所有會(huì)話屬性也會(huì)解除綁定如果客戶已經(jīng)不活動(dòng),或者你知道會(huì)話已經(jīng)結(jié)束(例如,客戶完成了購(gòu)物結(jié)賬,或已經(jīng)注銷),可以用這個(gè)方法殺死(撤銷)會(huì)話。會(huì)話實(shí)例本身可能會(huì)被容器回收,但是這一點(diǎn)我們并不關(guān)心。置無(wú)效(Invaldate)意味著會(huì)話ID不再存在,而且屬性會(huì)從會(huì)話對(duì)象刪除

    由UML提供給我們的信息,我們知道Session銷毀可以通過(guò)設(shè)置時(shí)長(zhǎng),和手動(dòng)刪除(invalidate())。

    還有一種死法:應(yīng)用結(jié)束(奔潰或取消部署)

    (1)在DD中配置會(huì)話超時(shí)

    <web-app ...><session-config><session-timeout>15</session-time></session-config> </web-app>

    (2)設(shè)置一個(gè)特定會(huì)話的會(huì)話超時(shí)

    session.setMaxInactiveInterval(20*60); //表示20分鐘生存時(shí)間

    cookie可以另作其他用處嗎?cookie是不是只能用于會(huì)話?

    可以使用cookie在服務(wù)器和客戶之間交換名/值String對(duì)。

    服務(wù)器把cookie發(fā)送給客戶,客戶再在以后的每個(gè)請(qǐng)求中發(fā)回這個(gè)cookie。

    客戶的瀏覽器退出時(shí),會(huì)話cookie就會(huì)消失,但是你可以告訴cookie在客戶端上待得更久一些,甚至在瀏覽器關(guān)閉之后還持久保存


    利用servlet API使用cookie


    代碼如下:

    //創(chuàng)建一個(gè)新Cookie Cookie cookie = new Cookie("username",name);//設(shè)置cookie在客戶端上存活多久 cookie.setMaxAge(30*60);//把cookie發(fā)送到客戶 response.addCookie(cookie);//從客戶請(qǐng)求得到cookie(或多個(gè)cookie) Cookie[] cookies = request.getCookies(); for(int i=0;i<cookies.length;i++){Cookie cookie = cookies[i];if(cookie.getName().equals("username")){String userName = cookie.getValue();out.println("Hello "+userName);break;} }

    cookie注意點(diǎn):


    HttpSession的重要里程碑

  • 創(chuàng)建或撤銷會(huì)話。
  • 由應(yīng)用的其他部分增加、刪除或替換會(huì)話屬性。
  • 會(huì)話在一個(gè)VM中鈍化,并在一個(gè)分布式應(yīng)用中的另一個(gè)VM中激活。
  • 會(huì)話生命周期時(shí)間

    里程碑事件和監(jiān)聽(tīng)者類型
    生命周期:創(chuàng)建(此時(shí)會(huì)話是新的)會(huì)話、撤銷(invalidate方法)會(huì)話HttpSessionEvent、HttpSessionListener
    屬性:增加、刪除、替換一個(gè)屬性HttpSessionBindingEvent、HttpSessionAttributeListener
    遷移:會(huì)話準(zhǔn)備鈍化、會(huì)話已經(jīng)激活HttpSessionEvent、HttpSessionActivationListener

    HttpSessionBindingListener實(shí)例:

    import javax.servlet.http.*; public class Dog implements HttpSessionBindingListener {private String breed;public Dog(String breed){this.breed = breed;}public String getBreed(){return breed;}public void valueBound(HttpSessionBindingEvent event){//我知道我在一個(gè)會(huì)話中時(shí)要運(yùn)行的代碼}public void valueUnbound(HttpSessionBindingEvent event){//我知道已經(jīng)不在一個(gè)會(huì)話中時(shí)要運(yùn)行的代碼}}

    啤酒Web應(yīng)用分布在兩個(gè)VM上

    HttpSessionActivationListener:
    會(huì)話遷移和串行化。
    容器需要遷移Serializable屬性(類的屬性要么為null要么是Serializable)。
    但是容器不一定非要使用串行化來(lái)遷移HttpSession對(duì)象(屬性類是Serializable)。

    這里指出:tomcat會(huì)把輸出(System.out.println())放在tomcat的logs/catalina.log文件中

    監(jiān)聽(tīng)者例子:

    會(huì)話計(jì)數(shù)器:這個(gè)監(jiān)聽(tīng)者允許你跟蹤這個(gè)Web應(yīng)用中活動(dòng)會(huì)話的個(gè)數(shù)。

    public class BeerSessionCounter implements HttpSessionListener {private static int activeSession;public static int getActiveSession(){return activeSession;}public void sessionCreated(HttpSessionEvent event){activeSession++;}public void sessionDestroyed(HttpSessionEvent event){activeSession--;}}

    屬性監(jiān)聽(tīng)者:利用這個(gè)監(jiān)聽(tīng)者,每一次向會(huì)話增加屬性、刪除屬性或替換屬性時(shí)你都能跟蹤到。

    public class BeerAttributeListener implements HttpSessionAttributeListener {public void attributeAdded(HttpSessionBindingEvent event){String name = event.getName();Object value = event.getValue();System.out.println("Attribute added: " + name + ": " + value)}public void attributeRemove(HttpSessionBindingEvent event){String name = event.getName();Object value = event.getValue();System.out.println("Attribute removed: " + name + ": " + value)}public void attributeReplaced(HttpSessionBindingEvent event){String name = event.getName();Object value = event.getValue();System.out.println("Attribute replaced: " + name + ": " + value)} }

    屬性類的監(jiān)聽(tīng)者:這個(gè)監(jiān)聽(tīng)者允許屬性跟蹤可能對(duì)屬性本身很重要事情,如增加到會(huì)話,或從會(huì)話刪除,已經(jīng)會(huì)話從一個(gè)VM遷移到另一個(gè)VM。

    public class Dog implements HttpSessionBindingListener,HttpSessionActivationListener,Serializable {private String breed;//假設(shè)這里還有更多實(shí)例變量,包括一些非Serializable的實(shí)例變量//假設(shè)這里是構(gòu)造函數(shù)已經(jīng)其他get/set方法public void valueBound(HttpSessionBindingEvent event){//我知道我在一個(gè)會(huì)話中時(shí)要運(yùn)行的代碼}public void valueUnbound(HttpSessionBindingEvent event){//我知道已經(jīng)不在一個(gè)會(huì)話中時(shí)要運(yùn)行的代碼}public void sessionWillPassivate(HttpSessionEvent event){//這些代碼將非Serializable字段置為某種狀態(tài),以便順利地遷移到一個(gè)新VM}public void sessionDidActivate(HttpSessionEvent event){//這些代碼用于回復(fù)字段...取消在sessionWillPassivate()中做的動(dòng)作}}

    DD文件配置

    <web-app ...><listener><listener-class>****.*Listener</listener-class></listener> </web-app>

    與會(huì)話相關(guān)的監(jiān)聽(tīng)者

    場(chǎng)景監(jiān)聽(tīng)者接口/方法事件類型通常由誰(shuí)實(shí)現(xiàn)
    你想知道有多少個(gè)并發(fā)用戶。也就是說(shuō),你想跟蹤活動(dòng)的會(huì)話HttpSessionListener(javax.servlet.http) sessionCreated、sessionDestroyedHttpSessionEvent其他類
    你想知道會(huì)話何時(shí)從一個(gè)VM移到另一個(gè)VMHttpSessionActivateListener(javax.servlet.http) sessionDidActivate、sessionWillPassivateHttpSessionEvent屬性類、其他類
    有一個(gè)屬性類(這個(gè)類的對(duì)象要用作為一個(gè)屬性值),而且你希望此類對(duì)象綁定到會(huì)話或從會(huì)話刪除時(shí)得到通知HttpSessionBindingListener(javax.servlet.http) valueBound、valueUnboundHttpSessionBindingEvent屬性類
    你想知道會(huì)話中什么時(shí)候增加、刪除、替換會(huì)話屬性HttpSessionAttributeListener(javax.servlet.http) attributeAdded、attributeRemoved、attributeReplacedHttpSessionBindingEvent其他類

    監(jiān)聽(tīng)者的UML圖


    本章完

    總結(jié)

    以上是生活随笔為你收集整理的Head First JSP---随笔四的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。

    如果覺(jué)得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。