WebService大讲堂之Axis2(5):会话(Session)

系统 1925 0

本文为原创,如需转载,请注明作者和出处,谢谢!

WebService 给人最直观的感觉就是由一个个方法组成,并在客户端通过 SOAP 协议调用这些方法。这些方法可能有返回值,也可能没有返回值。虽然这样可以完成一些工具,但这些被调用的方法是孤立的,当一个方法被调用后,在其他的方法中无法获得这个方法调用后的状态,也就是说无法保留状态。

读者可以想象,这对于一个完整的应用程序,无法保留状态,就意味着只依靠 WebService 很难完成全部的工作。例如,一个完整的应用系统都需要进行登录,这在 Web 应用中使用 Session 来保存用户登录状态,而如果用 WebService 的方法来进行登录处理,无法保存登录状态是非常令人尴尬的。当然,这也可以通过其他的方法来解决,如在服务端使用 static 变量来保存用户状态,并发送一个 id 到客户端,通过在服务端和客户端传递这个 id 来取得相应的用户状态。这非常类似于 Web 应用中通过 Session Cookie 来管理用户状态。但这就需要由开发人员做很多工作,不过幸好 Axis2 为我们提供了 WebService 状态管理的功能。

使用 Axis2 来管理 WebService 的状态基本上对于开发人员是透明的。在 WebService 类需要使用 org.apache.axis2.context.MessageContext org.apache.axis2.context.ServiceContext 类来保存与获得保存在服务端的状态信息,这有些象使用 HttpSession 接口的 getAttribute setAttribute 方法获得与设置 Session 域属性。

除此之外,还需要修改 services.xml 文件的内容,为 <service> 元素加一个 scope 属性,该属性有四个可取的值: Application, SOAPSession, TransportSession, Request ,不过要注意一下,虽然 Axis2 的官方文档将这四个值的单词首字母和缩写字母都写成了大写,但经笔者测试,必须全部小写才有效,也就是这四个值应为: application soapsession transportsession request ,其中 request scope 属性的默认值。读者可以选择使用 transportsession application 分别实现同一个 WebService 类和跨 WebService 类的会话管理。

在客户端需要使用 setManageSession(true) 打开 Session 管理功能。

综上所述,实现同一个 WebService Session 管理需要如下三步:

1. 使用 MessageContext ServiceContext 获得与设置 key-value 对。

2. 为要进行 Session 管理的 WebService 类所对应的 <service> 元素添加一个 scope 属性,并将该属性值设为 transportsession

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

下面是一个在同一个 WebService 类中管理 Session 的例子。

先建立一个WebService类,代码如下:


<!--<br /> <br /> Code highlighting produced by Actipro CodeHighlighter (freeware)<br /> http://www.CodeHighlighter.com/<br /> <br /> --> package service;
import org.apache.axis2.context.ServiceContext;
import org.apache.axis2.context.MessageContext;
public class LoginService
{
public boolean login(Stringusername,Stringpassword)
{
if ( " bill " .equals(username) && " 1234 " .equals(password))
{
// 第1步:设置key-value对
MessageContextmc = MessageContext.getCurrentMessageContext();
ServiceContextsc
= mc.getServiceContext();
sc.setProperty(
" login " , " 成功登录 " );
return true ;
}
else
{
return false ;
}
}
public StringgetLoginMsg()
{
// 第1步:获得key-value对中的value
MessageContextmc = MessageContext.getCurrentMessageContext();
ServiceContextsc
= mc.getServiceContext();
return (String)sc.getProperty( " login " );
}
}
<!--[if gte mso 9]><xml> Normal 0 7.8 磅 0 2 false false false MicrosoftInternetExplorer4 </xml><![endif]--><!--[if gte mso 9]><![endif]--> <!--[if gte mso 10]> <mce:style><! /* Style Definitions */ table.MsoNormalTable { mso-style-parent:""; font-size:10.0pt; font-family:"Times New Roman"; mso-fareast-font-family:"Times New Roman";} --> <!--[endif]-->

LoginService 类中有两个方法: login getLoginMsg ,如果 login 方法登录成功,会将“成功登录”字符串保存在 ServiceContext 对象中。如果在 login 方法返回 true 后调用 getLoginMsg 方法,就会返回“成功登录”。

下面是 LoginService 类的配置代码( services.xml ):

<!--<br /> <br /> Code highlighting produced by Actipro CodeHighlighter (freeware)<br /> http://www.CodeHighlighter.com/<br /> <br /> --> <!-- 第2步:添加scope属性 -->
< service name ="loginService" scope ="transportsession" >
< 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 >

<!--[if gte mso 9]><xml> Normal 0 7.8 磅 0 2 false false false MicrosoftInternetExplorer4 </xml><![endif]--><!--[if gte mso 9]><![endif]--> <!--[if gte mso 10]> <mce:style><! /* Style Definitions */ table.MsoNormalTable { mso-style-parent:""; font-size:10.0pt; font-family:"Times New Roman"; mso-fareast-font-family:"Times New Roman";} --> <!--[endif]-->

使用如下的命令生成客户端使用的 stub 类:

<!--<br /> <br /> Code highlighting produced by Actipro CodeHighlighter (freeware)<br /> http://www.CodeHighlighter.com/<br /> <br /> --> %AXIS2_HOME%\bin\wsdl2java-urihttp://localhost: 8080 /axis2/services/loginService?wsdl-pclient-s-ostub

<!--[if gte mso 9]><xml> Normal 0 7.8 磅 0 2 false false false MicrosoftInternetExplorer4 </xml><![endif]--><!--[if gte mso 9]><![endif]--> <!--[if gte mso 10]> <mce:style><! /* Style Definitions */ table.MsoNormalTable { mso-style-parent:""; font-size:10.0pt; font-family:"Times New Roman"; mso-fareast-font-family:"Times New Roman";} --> <!--[endif]-->

stub\src\client 目录中生成了一个 LoginServiceStub.java 类,在该类中找到如下的构造句方法:

<!--<br /> <br /> Code highlighting produced by Actipro CodeHighlighter (freeware)<br /> http://www.CodeHighlighter.com/<br /> <br /> --> public LoginServiceStub(org.apache.axis2.context.ConfigurationContextconfigurationContext,
java.lang.StringtargetEndpoint,
boolean useSeparateListener)
throws org.apache.axis2.AxisFault
{

_serviceClient.getOptions().setSoapVersionURI(org.apache.axiom.soap.SOAP12Constants.SOAP_ENVELOPE_NAMESPACE_URI);
}

<!--[if gte mso 10]> <mce:style><! /* Style Definitions */ table.MsoNormalTable { mso-style-parent:""; font-size:10.0pt; font-family:"Times New Roman"; mso-fareast-font-family:"Times New Roman";} --> <!--[endif]--> 在该方法中最后添加如下的代码:

<!--<br /> <br /> Code highlighting produced by Actipro CodeHighlighter (freeware)<br /> http://www.CodeHighlighter.com/<br /> <br /> --> // 第3步:打开客户端的Session管理功能
_serviceClient.getOptions().setManageSession( true );
<!--[if gte mso 9]><xml> Normal 0 7.8 磅 0 2 false false false MicrosoftInternetExplorer4 </xml><![endif]--><!--[if gte mso 9]><![endif]--> <!--[if gte mso 10]> <mce:style><! /* Style Definitions */ table.MsoNormalTable { mso-style-parent:""; font-size:10.0pt; font-family:"Times New Roman"; mso-fareast-font-family:"Times New Roman";} --> <!--[endif]-->

下面的客户端代码使用 LoginServiceStub 对象访问了刚才建立的 WebService

<!--<br /> <br /> Code highlighting produced by Actipro CodeHighlighter (freeware)<br /> http://www.CodeHighlighter.com/<br /> <br /> --> LoginServiceStubstub = new LoginServiceStub();
LoginServiceStub.Loginlogin
= new LoginServiceStub.Login();
login.setUsername(
" bill " );
login.setPassword(
" 1234 " );
if (stub.login(login).local_return)
{
System.out.println(stub.getLoginMsg().local_return);
}

<!--[if gte mso 9]><xml> Normal 0 7.8 磅 0 2 false false false MicrosoftInternetExplorer4 </xml><![endif]--><!--[if gte mso 9]><![endif]--> <!--[if gte mso 10]> <mce:style><! /* Style Definitions */ table.MsoNormalTable { mso-style-parent:""; font-size:10.0pt; font-family:"Times New Roman"; mso-fareast-font-family:"Times New Roman";} --> <!--[endif]-->


运行上面的代码后,会输出“成功登录”信息。

WebService大讲堂之Axis2(5):会话(Session)管理


更多文章、技术交流、商务合作、联系博主

微信扫码或搜索:z360901061

微信扫一扫加我为好友

QQ号联系: 360901061

您的支持是博主写作最大的动力,如果您喜欢我的文章,感觉我的文章对您有帮助,请用微信扫描下面二维码支持博主2元、5元、10元、20元等您想捐的金额吧,狠狠点击下面给点支持吧,站长非常感激您!手机微信长按不能支付解决办法:请将微信支付二维码保存到相册,切换到微信,然后点击微信右上角扫一扫功能,选择支付二维码完成支付。

【本文对您有帮助就好】

您的支持是博主写作最大的动力,如果您喜欢我的文章,感觉我的文章对您有帮助,请用微信扫描上面二维码支持博主2元、5元、10元、自定义金额等您想捐的金额吧,站长会非常 感谢您的哦!!!

发表我的评论
最新评论 总共0条评论