WebService大讲堂之Axis2(6):跨服务会话(Session)管理
在《WebService大讲堂之Axis2(5):会话(Session)管理》一文中介绍了如何使用Axis2来管理同一个服务的会话,但对于一个复杂的系统,不可能只有一个WebService服务,例如,至少会有一个管理用户的WebService(用户登录和注册)以及处理业务的WebService。象这种情况,就必须在多个WebService服务之间共享会话状态,也称为跨服务会话(Session)管理。实现跨服务会话管理与实现同一个服务的会话管理的步骤类似,但仍然有一些差别,实现跨服务会话管理的步骤如下: 实现跨服务的Session管理需要如下三步: 1.?使用MessageContext和ServiceGroupContext获得与设置key-value对。 2.?为要进行Session管理的WebService类所对应的<service>元素添加一个scope属性,并将该属性值设为application。 3.?在客户端使用setManageSession(true)打开Session管理功能。 从上面的步骤可以看出,实现跨服务会话管理与实现同一个服务的会话管理在前两步上存在着差异,而第3步是完全一样的。下面是一个跨服务的会话管理的实例。在这个例子中有两个WebService类:LoginService和SearchService,代码如下:
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 " );???? ????} }
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 ? " 找到的数据< " ? + ?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类的对象实例访问上面实现的两个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);? } 在执行上面的代码后,将输出如下的信息:
成功登录
找到的数据 < abc > 读者可以将scope属性值改成transportsession,看看会输出什么!
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,? out ?rs); if ?(r) { ????service1.searchService?ss? = ? new ?service1.searchService(); ????MessageBox.Show(ss.findByName( " abc " )); } 如果读者使用delphi(本文使用的是delphi2009,其他的delphi版本请读者自行测试)调用支持会话的WebService时有一些差别。经笔者测试,使用delphi调用WebService,将scope属性值设为transportsession和application都可以实现跨服务的会话管理,这一点和Java与C#不同,Java和C#必须将scope属性值设为application才支持跨服务会话管理。在delphi中不需要象C#指定一个CookieContainer或其他类似的对象,而只需要象访问普通的WebService一样访问支持会话的WebService即可。 http://www.blogjava.net/nokiaguy/archive/2009/01/archive/2009/01/archive/2009/01/archive/2009/01/archive/2009/nokiaguy/archive/2009/02/03/253154.html (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |