隨筆 - 312, 文章 - 14, 評(píng)論 - 1393, 引用 - 0

          導(dǎo)航

          <2009年2月>
          25262728293031
          1234567
          891011121314
          15161718192021
          22232425262728
          1234567

          公告

          關(guān)注我的新浪微博

          我的著作









          常用鏈接

          留言簿(126)

          我參與的團(tuán)隊(duì)

          隨筆分類(lèi)(818)

          隨筆檔案(310)

          文章分類(lèi)(1)

          文章檔案(8)

          相冊(cè)

          ADSL、3G查詢

          CSDN

          eclipse

          ibm

          Java EE

          Linux

          Web

          云服務(wù)

          代理網(wǎng)站

          關(guān)注的網(wǎng)站

          協(xié)議

          喜歡的Blog

          國(guó)內(nèi)廣告平臺(tái)

          圖書(shū)出版

          在線培訓(xùn)

          開(kāi)發(fā)工具

          微博客戶端

          手機(jī)鈴聲

          操作系統(tǒng)

          • ReactOS
          • 一個(gè)與windowXP/2003兼容的操作系統(tǒng)

          數(shù)學(xué)

          文件格式

          源碼資源

          移動(dòng)(Mobile)

          編程語(yǔ)言

          英語(yǔ)學(xué)習(xí)

          最新隨筆

          搜索

          •  

          積分與排名

          • 積分 - 1973742
          • 排名 - 6

          最新評(píng)論

          閱讀排行榜

          評(píng)論排行榜

          WebService大講堂之Axis2(6):跨服務(wù)會(huì)話(Session)管理

          本文為原創(chuàng),如需轉(zhuǎn)載,請(qǐng)注明作者和出處,謝謝!

          上一篇:WebService大講堂之Axis2(5):會(huì)話(Session)管理

          《WebService大講堂之Axis2(5):會(huì)話(Session)管理》一文中介紹了如何使用Axis2來(lái)管理同一個(gè)服務(wù)的會(huì)話,但對(duì)于一個(gè)復(fù)雜的系統(tǒng),不可能只有一個(gè)WebService服務(wù),例如,至少會(huì)有一個(gè)管理用戶的WebService(用戶登錄和注冊(cè))以及處理業(yè)務(wù)的WebService。象這種情況,就必須在多個(gè)WebService服務(wù)之間共享會(huì)話狀態(tài),也稱為跨服務(wù)會(huì)話(Session)管理。實(shí)現(xiàn)跨服務(wù)會(huì)話管理與實(shí)現(xiàn)同一個(gè)服務(wù)的會(huì)話管理的步驟類(lèi)似,但仍然有一些差別,實(shí)現(xiàn)跨服務(wù)會(huì)話管理的步驟如下:

          實(shí)現(xiàn)跨服務(wù)的Session管理需要如下三步:

          1. 使用MessageContextServiceGroupContext獲得與設(shè)置key-value對(duì)。

          2. 為要進(jìn)行Session管理的WebService類(lèi)所對(duì)應(yīng)的<service>元素添加一個(gè)scope屬性,并將該屬性值設(shè)為application

          3. 在客戶端使用setManageSession(true)打開(kāi)Session管理功能。

          從上面的步驟可以看出,實(shí)現(xiàn)跨服務(wù)會(huì)話管理與實(shí)現(xiàn)同一個(gè)服務(wù)的會(huì)話管理在前兩步上存在著差異,而第3步是完全一樣的。下面是一個(gè)跨服務(wù)的會(huì)話管理的實(shí)例。在這個(gè)例子中有兩個(gè)WebService類(lèi):LoginServiceSearchService,代碼如下:

          LoginService.java

          package service;
          import org.apache.axis2.context.MessageContext;
          import org.apache.axis2.context.ServiceGroupContext;
          public class LoginService
          {
              
          public boolean login(String username, String password)
              {        
                  
          if("bill".equals(username) && "1234".equals(password))
                  {
                      
          //  第1步:設(shè)置key-value對(duì)
                      MessageContext mc = MessageContext.getCurrentMessageContext();
                      ServiceGroupContext sgc 
          = mc.getServiceGroupContext();
                      sgc.setProperty(
          "login""成功登錄");    
                      
          return true;
                  }
                  
          else
                  {
                      
          return false;
                  }
              }    
              
          public String getLoginMsg()
              {
                 
          //  第1步:獲得key-value對(duì)中的value
                  MessageContext mc = MessageContext.getCurrentMessageContext();
                  ServiceGroupContext sgc 
          =  mc.getServiceGroupContext();
                  
          return (String)sgc.getProperty("login");    
              }
          }


          SearchService.java

          package service;
          import org.apache.axis2.context.MessageContext;
          import org.apache.axis2.context.ServiceGroupContext;
          public class SearchService
          {
              
          public String findByName(String name)
              {
                  
          //  第1步:獲得key-value對(duì)中的value
                  MessageContext mc = MessageContext.getCurrentMessageContext();
                  ServiceGroupContext sgc 
          =  mc.getServiceGroupContext();                
                  
          if (sgc.getProperty("login"!= null)
                      
          return "找到的數(shù)據(jù)<" + name + ">";
                  
          else
                      
          return "用戶未登錄";
              }
          }

          services.xml文件中的配置代碼如下:

          <serviceGroup>
              
          <!--  第2步:添加scope屬性,并設(shè)置屬性值為application -->
              
          <service name="loginService" scope="application">
                  
          <description>
                      登錄服務(wù)
                  
          </description>
                  
          <parameter name="ServiceClass">
                      service.LoginService
                  
          </parameter>
                  
          <messageReceivers>
                      
          <messageReceiver mep="http://www.w3.org/2004/08/wsdl/in-out"
                          class
          ="org.apache.axis2.rpc.receivers.RPCMessageReceiver" />
                  
          </messageReceivers>
              
          </service>
              
          <!--  第2步:添加scope屬性,并設(shè)置屬性值為application -->
              
          <service name="searchService" scope="application">
                  
          <description>
                      搜索服務(wù)
                  
          </description>
                  
          <parameter name="ServiceClass">
                      service.SearchService
                  
          </parameter>
                  
          <messageReceivers>
                      
          <messageReceiver mep="http://www.w3.org/2004/08/wsdl/in-out"
                          class
          ="org.apache.axis2.rpc.receivers.RPCMessageReceiver" />
                  
          </messageReceivers>
              
          </service>
          </serviceGroup>


          3步與《WebService大講堂之Axis2(5):會(huì)話(Session)管理》一文中介紹的方法類(lèi)似。

          下面是使用兩個(gè)stub類(lèi)的對(duì)象實(shí)例訪問(wèn)上面實(shí)現(xiàn)的兩個(gè)WebService的客戶端代碼:

          LoginServiceStub stub = new LoginServiceStub();
          LoginServiceStub.Login login 
          = new LoginServiceStub.Login();
          login.setUsername(
          "bill");
          login.setPassword(
          "1234");
          if(stub.login(login).local_return)
          {
              System.out.println(stub.getLoginMsg().local_return);
              SearchServiceStub searchStub 
          = new SearchServiceStub();
              SearchServiceStub.FindByName fbn 
          = new SearchServiceStub.FindByName();
              fbn.setName(
          "abc");
              System.out.println(searchStub.findByName(fbn).local_return); 
          }

          在執(zhí)行上面的代碼后,將輸出如下的信息:

          成功登錄

          找到的數(shù)據(jù)
          <abc>

          讀者可以將scope屬性值改成transportsession,看看會(huì)輸出什么!

              實(shí)際上,Axis2的會(huì)話管理也是通過(guò)Cookie實(shí)現(xiàn)的,與Web應(yīng)用中的Session管理類(lèi)似。如果讀者使用C#訪問(wèn)支持會(huì)話(在同一個(gè)服務(wù)中的會(huì)話管理)的WebService,需要指定一個(gè)CookieContainer對(duì)象,代碼如下:

          service.loginService ls = new service.loginService();
          System.Net.CookieContainer cc 
          = new System.Net.CookieContainer();
          ls.CookieContainer 
          = cc;
          bool r, rs;
          ls.login(
          "bill""1234"out @r, out rs);
          if (r)
          {
              MessageBox.Show(ls.getLoginMsg().@return);
          }

          如果是訪問(wèn)跨服務(wù)的支持會(huì)話的WebService,則不需要指定CookieContainer對(duì)象,代碼如下:

          service.loginService ls = new service.loginService();
          bool r, rs;
          ls.login(
          "bill""1234"out @r, out rs);
          if (r)
          {
              service1.searchService ss 
          = new service1.searchService();
              MessageBox.Show(ss.findByName(
          "abc"));
          }

          如果讀者使用delphi(本文使用的是delphi2009,其他的delphi版本請(qǐng)讀者自行測(cè)試)調(diào)用支持會(huì)話的WebService時(shí)有一些差別。經(jīng)筆者測(cè)試,使用delphi調(diào)用WebService,將scope屬性值設(shè)為transportsessionapplication都可以實(shí)現(xiàn)跨服務(wù)的會(huì)話管理,這一點(diǎn)和JavaC#不同,JavaC#必須將scope屬性值設(shè)為application才支持跨服務(wù)會(huì)話管理。在delphi中不需要象C#指定一個(gè)CookieContainer或其他類(lèi)似的對(duì)象,而只需要象訪問(wèn)普通的WebService一樣訪問(wèn)支持會(huì)話的WebService即可。

          下一篇:
          WebService大講堂之Axis2(7):將Spring的裝配JavaBean發(fā)布成WebService





          Android開(kāi)發(fā)完全講義(第2版)(本書(shū)版權(quán)已輸出到臺(tái)灣)

          http://product.dangdang.com/product.aspx?product_id=22741502



          Android高薪之路:Android程序員面試寶典 http://book.360buy.com/10970314.html


          新浪微博:http://t.sina.com.cn/androidguy   昵稱:李寧_Lining

          posted on 2009-02-03 23:42 銀河使者 閱讀(13847) 評(píng)論(20)  編輯  收藏 所屬分類(lèi): java 原創(chuàng)webservice

          評(píng)論

          # re: WebService大講堂之Axis2(6):跨服務(wù)會(huì)話(Session)管理  回復(fù)  更多評(píng)論   

          謝謝你的文章,很有用阿
          2009-02-05 13:38 | IT公司面試手冊(cè)

          # re: WebService大講堂之Axis2(6):跨服務(wù)會(huì)話(Session)管理  回復(fù)  更多評(píng)論   

          大哥,牛人啊~~贊
          2009-02-05 23:33 | zuzong

          # re: WebService大講堂之Axis2(6):跨服務(wù)會(huì)話(Session)管理  回復(fù)  更多評(píng)論   

          文章很有用,想問(wèn)一個(gè)問(wèn)題,
          怎樣實(shí)現(xiàn)超時(shí)自動(dòng)終止會(huì)話呢?
          2009-02-07 13:31 | yapituy

          # re: WebService大講堂之Axis2(6):跨服務(wù)會(huì)話(Session)管理  回復(fù)  更多評(píng)論   

          我每次使用相同的客戶端訪問(wèn),以前會(huì)話的內(nèi)容還都存在,怎樣才能使長(zhǎng)時(shí)間不用的會(huì)話自動(dòng)斷開(kāi)
          2009-02-07 13:34 | yapituy

          # re: WebService大講堂之Axis2(6):跨服務(wù)會(huì)話(Session)管理  回復(fù)  更多評(píng)論   

          這是application級(jí)別的,只有服務(wù)器重啟或重新發(fā)布應(yīng)用程序會(huì)話才會(huì)消失。而其他級(jí)別的我試了一下,并不能跨服務(wù)共享會(huì)話。
          2009-02-07 17:18 | 銀河使者

          # re: WebService大講堂之Axis2(6):跨服務(wù)會(huì)話(Session)管理  回復(fù)  更多評(píng)論   

          有個(gè)項(xiàng)目,我準(zhǔn)備使用application級(jí)別的會(huì)話管理,但客戶端比較多,如果保存那么多的會(huì)話而不斷開(kāi)的話,會(huì)不會(huì)對(duì)服務(wù)器造成很大的壓力?又沒(méi)什么比較好的解決方法實(shí)現(xiàn)會(huì)話的超時(shí)斷開(kāi)的功能?謝謝!
          2009-02-07 21:16 | yapituy

          # re: WebService大講堂之Axis2(6):跨服務(wù)會(huì)話(Session)管理  回復(fù)  更多評(píng)論   

          不知你的用戶有多少,10000,還是20000,或更多,一個(gè)會(huì)話只占很小的內(nèi)存。當(dāng)然,除了使用會(huì)話解決你的問(wèn)題外,還有另外一個(gè)方法可以達(dá)到同樣的效果。使用會(huì)話的目的是為了進(jìn)行權(quán)限驗(yàn)證,你可以為每一個(gè)web service方法都加上一個(gè)用戶名和密碼,可以將這些放到類(lèi)中進(jìn)行傳遞,這樣就不需要會(huì)話了,每次調(diào)用方法程序都從數(shù)據(jù)庫(kù)中驗(yàn)證,你也可以定義一個(gè)靜態(tài)的Map對(duì)象在服務(wù)端來(lái)保存經(jīng)常登錄的用戶名和密碼,這樣當(dāng)這些用戶調(diào)用該方法時(shí)就不用再到數(shù)據(jù)庫(kù)中去驗(yàn)證了。如博客園和blogjava所使用的msn writer寫(xiě)blog,就是使用的MetaWebBlog API,這個(gè)API雖然不是Web Service(只是一個(gè)遠(yuǎn)程方法調(diào)用),但使用的就是我說(shuō)的第二種方法,每一方法都有一個(gè)用戶名和密碼。你看看這些方法就知道了:http://www.cnblogs.com/nokiaguy/services/metaweblog.aspx
          2009-02-07 21:34 | 銀河使者

          # re: WebService大講堂之Axis2(6):跨服務(wù)會(huì)話(Session)管理  回復(fù)  更多評(píng)論   

          另外會(huì)話是可以持久化的,但不知axis2是如何處理的
          2009-02-07 21:35 | 銀河使者

          # re: WebService大講堂之Axis2(6):跨服務(wù)會(huì)話(Session)管理  回復(fù)  更多評(píng)論   

          能否在登錄的時(shí)候在會(huì)話中記錄登錄時(shí)間,然后每次調(diào)用方法前,取當(dāng)前時(shí)間進(jìn)行判斷,如果時(shí)間間隔大于你的設(shè)定值,無(wú)法繼續(xù)操作,需要重新登錄?
          2009-02-09 16:44 | jiangminjie

          # re: WebService大講堂之Axis2(6):跨服務(wù)會(huì)話(Session)管理  回復(fù)  更多評(píng)論   

          @jiangminjie
          也可以,這種方法
          2009-02-09 16:51 | 銀河使者

          # re: WebService大講堂之Axis2(6):跨服務(wù)會(huì)話(Session)管理  回復(fù)  更多評(píng)論   

          呵呵,修改了一下ConfigurationContext類(lèi),在處理application會(huì)話時(shí),增加了一個(gè)處理超時(shí)的方法。
          2009-02-10 11:06 | yapituy

          # re: WebService大講堂之Axis2(6):跨服務(wù)會(huì)話(Session)管理  回復(fù)  更多評(píng)論   

          還得請(qǐng)教問(wèn)題,關(guān)于handler中拋出AxisFault異常的。
          在handler(使用java)中判斷用戶是否登陸,如果未登錄拋出一個(gè)AxisFault異常。客戶端(使用c#)無(wú)法捕獲此異常,捕捉到的異常是InvalidOperationException,但如果在service中拋出AxisFault,客戶端可以捕獲SoapException。怎樣處理客戶端才能捕獲到handler中的SoapException?謝謝 !
          2009-02-10 11:27 | yapituy

          # re: WebService大講堂之Axis2(6):跨服務(wù)會(huì)話(Session)管理  回復(fù)  更多評(píng)論   

          @yapituy
          這個(gè)我也試了,但客戶端也是未補(bǔ)獲AxisFault異常,我用java、c#和delphi試的客戶端,都未補(bǔ)獲AxisFault異常,不知axis2內(nèi)部是如何處理的,也許是有bug,也許是服務(wù)端程序的設(shè)置問(wèn)題,最終還沒(méi)解決,還是就是超時(shí)的問(wèn)題,可能是axis2本身的問(wèn)題。
          2009-02-10 11:46 | 銀河使者

          # re: WebService大講堂之Axis2(6):跨服務(wù)會(huì)話(Session)管理  回復(fù)  更多評(píng)論   

          我問(wèn)題中說(shuō)的可能有點(diǎn)亂,在服務(wù)端拋出AxisFault,c#客戶端捕捉到SoapException異常應(yīng)該是正確的。上午說(shuō)的問(wèn)題應(yīng)該是handler配置的有問(wèn)題,只配InFlow就可以捕捉到SoapException了,而我把OutFlow、InFaultFlow、OutFaultFlow也都給配置上了。
          2009-02-10 14:36 | yapituy

          # re: WebService大講堂之Axis2(6):跨服務(wù)會(huì)話(Session)管理  回復(fù)  更多評(píng)論   

          這路有一個(gè)問(wèn)題,如果我的用戶名密碼是存在數(shù)據(jù)庫(kù)里面的,一旦我對(duì)一個(gè)用戶修改密碼或者干脆就刪除掉這個(gè)用戶,那么這樣就必須重啟服務(wù)器才能在驗(yàn)證這部分生效;所以目前這個(gè)實(shí)現(xiàn)辦法還是不能夠接受的,必須能夠讓session內(nèi)的東西自動(dòng)超時(shí)才行。
          既然scope 為應(yīng)用級(jí)別的,可以想辦法用另外一個(gè)線程去維護(hù)用戶信息的超時(shí)狀態(tài)
          2009-02-17 12:10 | Alexwan

          # re: WebService大講堂之Axis2(6):跨服務(wù)會(huì)話(Session)管理  回復(fù)  更多評(píng)論   

          @Alexwan
          如果用戶修改密碼,可以在修改密碼后將session里的相關(guān)內(nèi)容刪除,這樣客戶端必須要重新登錄才能繼續(xù)使用了。
          2009-02-17 12:19 | 銀河使者

          # re: WebService大講堂之Axis2(6):跨服務(wù)會(huì)話(Session)管理[未登錄](méi)  回復(fù)  更多評(píng)論   

          @銀河使者
          我也想問(wèn)問(wèn)怎么把session里的相關(guān)內(nèi)容刪除?
          最好能徹底將這個(gè)session刪除。
          2009-09-04 15:41 | todd

          # re: WebService大講堂之Axis2(6):跨服務(wù)會(huì)話(Session)管理  回復(fù)  更多評(píng)論   

          我用Java實(shí)現(xiàn)的,沒(méi)想到將scope設(shè)置成transportsession和application都能夠跨服務(wù)訪問(wèn),暈死了,還有,我沒(méi)有實(shí)現(xiàn)博主說(shuō)的第三步,實(shí)驗(yàn)了N次了,哎,不曉得這個(gè)原理到底是怎么回事了
          2010-01-05 12:05 | Mr.Blue

          # re: WebService大講堂之Axis2(6):跨服務(wù)會(huì)話(Session)管理  回復(fù)  更多評(píng)論   

          樓主你好 我在scope中設(shè)置了application但是訪問(wèn)結(jié)果還是跟設(shè)置了transportsession一樣 不能跨服務(wù)會(huì)話 請(qǐng)問(wèn)這是為什么
          <serviceGroup>

          <service name="ManageSession" scope="application">
          <description>
          This is my first webservice which use session.
          </description>
          <parameter name="ServiceClass">com.sha0k.webservice.session.LoginService</parameter>
          <operation name="login">
          <messageReceiver class="org.apache.axis2.rpc.receivers.RPCMessageReceiver" />
          </operation>
          <operation name="getLoginMsg">
          <messageReceiver class="org.apache.axis2.rpc.receivers.RPCMessageReceiver" />
          </operation>
          </service>

          <service name="SearchSession" scope="application">
          <description>
          This is my first webservice which use application session.
          </description>
          <parameter name="ServiceClass">com.sha0k.webservice.session.SearchService</parameter>
          <operation name="findByName">
          <messageReceiver class="org.apache.axis2.rpc.receivers.RPCMessageReceiver" />
          </operation>
          </service>

          </serviceGroup>
          2011-11-21 23:45 | sha0kun

          # re: WebService大講堂之Axis2(6):跨服務(wù)會(huì)話(Session)管理  回復(fù)  更多評(píng)論   

          我的客戶端 session管理 是開(kāi)啟的 RPCServiceClient serviceClient = new RPCServiceClient();
          Options options = serviceClient.getOptions();
          options.setManageSession(true);
          2011-11-21 23:46 | sha0kun
          主站蜘蛛池模板: 兴国县| 津市市| 达孜县| 扶绥县| 聂荣县| 天台县| 象州县| 广德县| 蒙山县| 镇安县| 宜昌市| 拜泉县| 衡阳县| 南宁市| 仁布县| 贵溪市| 囊谦县| 社会| 盘锦市| 南康市| 横峰县| 璧山县| 大竹县| 美姑县| 镇平县| 凤凰县| 辽阳市| 马关县| 巫溪县| 牡丹江市| 黑龙江省| 拉孜县| 林口县| 民勤县| 克山县| 惠来县| 响水县| 鱼台县| 尼木县| 黄龙县| 常山县|