隨筆 - 312, 文章 - 14, 評論 - 1393, 引用 - 0

          導(dǎo)航

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

          公告

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

          我的著作









          常用鏈接

          留言簿(126)

          我參與的團(tuán)隊

          隨筆分類(818)

          隨筆檔案(310)

          文章分類(1)

          文章檔案(8)

          相冊

          ADSL、3G查詢

          CSDN

          eclipse

          ibm

          Java EE

          Linux

          Web

          云服務(wù)

          代理網(wǎng)站

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

          協(xié)議

          喜歡的Blog

          國內(nèi)廣告平臺

          圖書出版

          在線培訓(xùn)

          開發(fā)工具

          微博客戶端

          手機鈴聲

          操作系統(tǒng)

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

          數(shù)學(xué)

          文件格式

          源碼資源

          移動(Mobile)

          編程語言

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

          最新隨筆

          搜索

          •  

          積分與排名

          • 積分 - 1974691
          • 排名 - 6

          最新評論

          閱讀排行榜

          評論排行榜

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

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

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

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

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

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

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

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

          從上面的步驟可以看出,實現(xiàn)跨服務(wù)會話管理與實現(xiàn)同一個服務(wù)的會話管理在前兩步上存在著差異,而第3步是完全一樣的。下面是一個跨服務(wù)的會話管理的實例。在這個例子中有兩個WebService類: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對
                      MessageContext mc = MessageContext.getCurrentMessageContext();
                      ServiceGroupContext sgc 
          = mc.getServiceGroupContext();
                      sgc.setProperty(
          "login""成功登錄");    
                      
          return true;
                  }
                  
          else
                  {
                      
          return false;
                  }
              }    
              
          public String getLoginMsg()
              {
                 
          //  第1步:獲得key-value對中的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對中的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):會話(Session)管理》一文中介紹的方法類似。

          下面是使用兩個stub類的對象實例訪問上面實現(xiàn)的兩個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,看看會輸出什么!

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

          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ù)的支持會話的WebService,則不需要指定CookieContainer對象,代碼如下:

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

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





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

          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 銀河使者 閱讀(13853) 評論(20)  編輯  收藏 所屬分類: java 原創(chuàng)webservice

          評論

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

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

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

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

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

          文章很有用,想問一個問題,
          怎樣實現(xiàn)超時自動終止會話呢?
          2009-02-07 13:31 | yapituy

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

          呵呵,修改了一下ConfigurationContext類,在處理application會話時,增加了一個處理超時的方法。
          2009-02-10 11:06 | yapituy

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

          樓主你好 我在scope中設(shè)置了application但是訪問結(jié)果還是跟設(shè)置了transportsession一樣 不能跨服務(wù)會話 請問這是為什么
          <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ù)會話(Session)管理  回復(fù)  更多評論   

          我的客戶端 session管理 是開啟的 RPCServiceClient serviceClient = new RPCServiceClient();
          Options options = serviceClient.getOptions();
          options.setManageSession(true);
          2011-11-21 23:46 | sha0kun
          主站蜘蛛池模板: 诸城市| 青冈县| 什邡市| 兴文县| 楚雄市| 新安县| 新宾| 云阳县| 上林县| 麻江县| 延安市| 巴彦县| 金昌市| 高邑县| 宁都县| 连南| 阜南县| 玉林市| 双牌县| 阳新县| 宜章县| 西平县| 思茅市| 平远县| 广州市| 岳西县| 辽源市| 常熟市| 木兰县| 阿图什市| 天峻县| 开阳县| 巢湖市| 和静县| 德化县| 堆龙德庆县| 嵩明县| 曲阳县| 荣成市| 万山特区| 张家口市|