<rt id="bn8ez"></rt>
<label id="bn8ez"></label>

  • <span id="bn8ez"></span>

    <label id="bn8ez"><meter id="bn8ez"></meter></label>

    隨筆 - 312, 文章 - 14, 評論 - 1393, 引用 - 0
    數(shù)據(jù)加載中……

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

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

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

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

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

    1. 使用MessageContextServiceGroupContext獲得與設置key-value對。

    2. 為要進行Session管理的WebService類所對應的<service>元素添加一個scope屬性,并將該屬性值設為application。

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

    從上面的步驟可以看出,實現(xiàn)跨服務會話管理與實現(xiàn)同一個服務的會話管理在前兩步上存在著差異,而第3步是完全一樣的。下面是一個跨服務的會話管理的實例。在這個例子中有兩個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步:設置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屬性,并設置屬性值為application -->
        
    <service name="loginService" scope="application">
            
    <description>
                登錄服務
            
    </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屬性,并設置屬性值為application -->
        
    <service name="searchService" scope="application">
            
    <description>
                搜索服務
            
    </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應用中的Session管理類似。如果讀者使用C#訪問支持會話(在同一個服務中的會話管理)的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);
    }

    如果是訪問跨服務的支持會話的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屬性值設為transportsessionapplication都可以實現(xiàn)跨服務的會話管理,這一點和JavaC#不同,JavaC#必須將scope屬性值設為application才支持跨服務會話管理。在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 銀河使者 閱讀(13841) 評論(20)  編輯  收藏 所屬分類: java 原創(chuàng) 、webservice

    評論

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    我的客戶端 session管理 是開啟的 RPCServiceClient serviceClient = new RPCServiceClient();
    Options options = serviceClient.getOptions();
    options.setManageSession(true);
    2011-11-21 23:46 | sha0kun
    主站蜘蛛池模板: 美女羞羞视频免费网站| 777爽死你无码免费看一二区| 中文字幕亚洲日韩无线码| 久久国产乱子伦精品免费看| 亚洲综合激情另类小说区| 免费高清资源黄网站在线观看| h视频在线免费观看| 亚洲自偷自拍另类图片二区| 日韩伦理片电影在线免费观看| 两个人日本免费完整版在线观看1| 亚洲日本在线播放| 亚洲欧洲精品成人久久奇米网| 96免费精品视频在线观看| 爱情岛亚洲论坛在线观看| 久久亚洲一区二区| 四虎永久免费地址在线网站| 99久久久国产精品免费牛牛| 男男gay做爽爽免费视频| 亚洲黄色中文字幕| 亚洲国产精品无码久久九九 | caoporn国产精品免费| 亚洲成人网在线播放| 亚洲日韩国产一区二区三区| 成人免费观看一区二区| 一区二区三区免费在线观看| 久久久久精品国产亚洲AV无码| 中文字幕亚洲专区| 日本特黄特色免费大片| 3d动漫精品啪啪一区二区免费| 一级做a爱过程免费视| 亚洲一卡一卡二新区无人区| 亚洲国产成人久久综合一| 亚洲成av人片在线观看天堂无码 | 最近中文字幕国语免费完整 | 亚洲欧洲免费无码| 日韩精品无码免费视频| 亚洲一本之道高清乱码| 亚洲成a人片在线观看无码专区| 免费在线观看视频a| 韩国18福利视频免费观看| 2021免费日韩视频网|