随笔 - 312, 文章 - 14, 评论 - 1393, 引用 - 0

导航

<2009年1月>
28293031123
45678910
11121314151617
18192021222324
25262728293031
1234567

公告

关注我的新浪微博

我的著作









常用链接

留言簿(126)

我参与的团队

随笔分类(818)

随笔档案(310)

文章分类(1)

文章档案(8)

相册

ADSL、3G查询

CSDN

eclipse

ibm

Java EE

Linux

Web

云服务

代理网站

关注的网站

协议

喜欢的Blog

国内广告平台

图书出版

在线培训

开发工具

微博客户端

手机铃声

操作系统

  • ReactOS
  • 一个与windowXP/2003兼容的操作系统

数学

文件格式

源码资源

移动(Mobile)

编程语言

英语学习

最新随笔

搜索

  •  

积分与排名

  • 积分 - 1969740
  • 排名 - 6

最新评论

阅读排行榜

评论排行榜

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

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


上一篇:WebService大讲堂之Axis2(4):二进制文件传输

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

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

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

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

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

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

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

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

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

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

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


package service;
import org.apache.axis2.context.ServiceContext;
import org.apache.axis2.context.MessageContext;
public class LoginService
{
    
public boolean login(String username, String password)
    {
        
if("bill".equals(username) && "1234".equals(password))
        {
            
//  第1步:设置key-value对
            MessageContext mc = MessageContext.getCurrentMessageContext();
            ServiceContext sc 
= mc.getServiceContext();
            sc.setProperty(
"login""成功登录");    
            
return true;
        }
        
else
        {
            
return false;
        }
    }
    
public String getLoginMsg()
    {
        
//  第1步:获得key-value对中的value
        MessageContext mc = MessageContext.getCurrentMessageContext();
        ServiceContext sc 
= mc.getServiceContext();
        
return (String)sc.getProperty("login");    
    }
}

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

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

<!--  第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>

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

%AXIS2_HOME%\bin\wsdl2java -uri http://localhost:8080/axis2/services/loginService?wsdl -p client -s -o stub

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

public LoginServiceStub(org.apache.axis2.context.ConfigurationContext configurationContext,
        java.lang.String targetEndpoint, 
boolean useSeparateListener)
        
throws org.apache.axis2.AxisFault 
{
     
    _serviceClient.getOptions().setSoapVersionURI(
                                 org.apache.axiom.soap.SOAP12Constants.SOAP_ENVELOPE_NAMESPACE_URI);
}

在该方法中最后添加如下的代码:

//  第3步:打开客户端的Session管理功能
_serviceClient.getOptions().setManageSession(true);

下面的客户端代码使用LoginServiceStub对象访问了刚才建立的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);
}

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

下一篇:
WebService大讲堂之Axis2(6):跨服务会话(Session)管理





Android开发完全讲义(第2版)(本书版权已输出到台湾)

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-01-26 00:00 银河使者 阅读(18504) 评论(31)  编辑  收藏 所属分类: java 原创webservice

评论

# re: WebService大讲堂之Axis2(5):会话(Session)管理  回复  更多评论   

我按照楼主的方法,可是为什么System.out.println(stub.getLoginMsg().local_return);得到的为null?
2009-04-28 18:16 | Sophie

# re: WebService大讲堂之Axis2(5):会话(Session)管理  回复  更多评论   

看看services.xml文件设置是否正确
2009-04-28 19:42 | 银河使者

# re: WebService大讲堂之Axis2(5):会话(Session)管理  回复  更多评论   

我就是把你的例子复制粘贴的。
同时,我看网上其他人的帖子说,要修改axis2.xml,增加<parameter name="manageTransportSession" locked="false">true</parameter>。
我试了以后还是不好使。我按照您在“WebService大讲堂之Axis2(6):跨服务会话(Session)管理”中的讲解,跨服务会话管理是好使的。
2009-04-29 10:49 | Sophie

# re: WebService大讲堂之Axis2(5):会话(Session)管理  回复  更多评论   

老大,我这边没有local_return啊,
System.out.println(stub.getLoginMsg().local_return);
只有
System.out.println(stub.getLoginMsg().get_return());
那个LoginServiceStub也是我wsdl2java自动生成的,我那个syso能够成功运行。
2009-05-18 21:27 | Harold.Zhang

# re: WebService大讲堂之Axis2(5):会话(Session)管理  回复  更多评论   

@Harold.Zhang
我的有啊,不知你是怎么生成的,编写和我的一样吗?
你的get_return可以返回值吗?
2009-05-18 22:25 | 银河使者

# re: WebService大讲堂之Axis2(5):会话(Session)管理[未登录]  回复  更多评论   

您好,再请教一下,我按照上面的内容,写好了webservice代码、service.xml 然后把它们打包为ws.aar,也放入到了tomcat下,接下来的调用,我没有按照上面的自动生成的代码,而是用前面的例子改了一下
public static void main(String[] args) throws Exception
{

RPCServiceClient serviceClient = new RPCServiceClient();
Options options = serviceClient.getOptions();
options.setManageSession(true);
String url=" http://localhost:8080/axis2/services/loginService";
EndpointReference targetEPR = new EndpointReference(url);
options.setTo(targetEPR);
Object[] opAddEntryArgs = new Object[] {"bill","1234"};
Class[] classes = new Class[] {String.class};
QName opAddEntry = new QName("http://service", "login");
System.out.println(serviceClient.invokeBlocking(opAddEntry, opAddEntryArgs, classes)[0]);

}
我这里把login的返回值稍做了修改。
但是运行这段代码,报Exception in thread "main" org.apache.axis2.AxisFault: Transport out has not been set异常,在google里搜了半天也没有好的解释……
2009-05-21 14:47 | 菜鸟

# re: WebService大讲堂之Axis2(5):会话(Session)管理  回复  更多评论   

不使用stub有时很麻烦。我一般很少使用其他方式调用。你的那段代码就算调试成功,以后用时也会很麻烦,只是调用了一个方法,弄这么一大堆代码。关于RPC还有有其他方式,只需要了解一下原理就可以。至于真正开发时,一般都用stub。你见用过.net调用webservice用这么多代码吗?哈哈
2009-05-21 14:52 | 银河使者

# re: WebService大讲堂之Axis2(5):会话(Session)管理[未登录]  回复  更多评论   

如果使用stub,我觉得对初学的人比较麻烦的一点是,对于命令生成的代码,共有2000多行,我们应该修改那一个方法呢?自己的代码又该放到什么位置合适呢?这个感觉比较疼痛,请指教,因为我也发现如果自己写代码调用service是比较麻烦一点。另外对于异常org.apache.axis2.AxisFault: Transport out has not been set,你以前在开发时碰到过吗?
2009-05-22 14:08 | 菜鸟

# re: WebService大讲堂之Axis2(5):会话(Session)管理  回复  更多评论   

stub不是用来修改的,是用来调用了,就将stub当成普通类好了(普通的Java类怎么用,stub类就怎么用)。

你的异常我没遇到过。我使用其他方法只是做测试。实际应用还是用stub的。否则会很麻烦。
2009-05-22 14:20 | 银河使者

# re: WebService大讲堂之Axis2(5):会话(Session)管理[未登录]  回复  更多评论   

终于知道错误原因了,String url=" http://localhost:8080/axis2/services/loginService";把http之前的空格去掉就好了,唉,真是没想到啊。呵呵。继续学习WebService大讲堂之Axis2。
2009-05-22 14:39 | 菜鸟

# re: WebService大讲堂之Axis2(5):会话(Session)管理  回复  更多评论   

Exception in thread "main" org.apache.axis2.AxisFault: Exception occurred while trying to invoke service method login
at org.apache.axis2.util.Utils.getInboundFaultFromMessageContext(Utils.java:512)
at org.apache.axis2.description.OutInAxisOperationClient.handleResponse(OutInAxisOperation.java:370)
at org.apache.axis2.description.OutInAxisOperationClient.send(OutInAxisOperation.java:416)
at org.apache.axis2.description.OutInAxisOperationClient.executeImpl(OutInAxisOperation.java:228)
at org.apache.axis2.client.OperationClient.execute(OperationClient.java:163)
at service.LoginServiceStub.login(LoginServiceStub.java:199)
at service.Client.main(Client.java:16)


我按你的步骤来,总是报这个异常,为什么呢?
2009-08-30 21:05 | 冷风

# re: WebService大讲堂之Axis2(5):会话(Session)管理  回复  更多评论   

为什么我在setProperty之后发现getProperty出来的中文是乱码?
2009-09-24 15:18 | orangehome

# re: WebService大讲堂之Axis2(5):会话(Session)管理  回复  更多评论   

请问,我按照整个流程下来,"成功登陆"都可以正常输出,可是这一节的会话管理,重在实现session保存登录信息的功能.
为什么当我发布了WS以后,进行过一次的客户端登录,按道理已经保留了
sc.getProperty("login")的登录信息.

但是,tomcat没停,直接运行System.out.println(stub.getMessage().get_return());,打印却是null,这是什么原因呢?

所以,我觉得session管理的实现,好像没有成功.
2009-09-27 18:05 | zhangx

# re: WebService大讲堂之Axis2(5):会话(Session)管理  回复  更多评论   

没动手操作过,只是想说一下个人的理解,不知道对不对?
加上scope="transportsession",理解就是那个服务是属于transportsession级别的服务了,也就是说这个变更在transportsession超时前这个实例对象是不会消失的,既然不会消失,就没必要放到ServiceContext中。

另外
2009-10-16 14:25 | china-qd

# re: WebService大讲堂之Axis2(5):会话(Session)管理  回复  更多评论   

@冷风
我也遇到了这个问题,百思不得其解,还望高人指点一二
2009-11-03 10:25 | Mr.Blue

# re: WebService大讲堂之Axis2(5):会话(Session)管理  回复  更多评论   

您好,我按照你的步骤,再没有进行第三步的情况下也能得到正确的结果,加上也能得到正确的结果,所以我怀疑是不是第三步可以省略,还是加上第三步才能确保得到正确的结果,没有第三步可能会得到正确的结果,也可能不会?
2009-11-03 11:22 | Mr.Blue

# re: WebService大讲堂之Axis2(5):会话(Session)管理  回复  更多评论   

@zhangx
个人认为,这位兄弟对同一个WebService的Session管理这里的理解出现了偏差,你说的那个问题我想应该是跨服务会话的管理了。一点愚见
2009-12-31 18:05 | Mr.Blue

# re: WebService大讲堂之Axis2(5):会话(Session)管理  回复  更多评论   

我也按照您的代码操作,输出结果是null
2010-06-15 18:38 | nihao

# re: WebService大讲堂之Axis2(5):会话(Session)管理  回复  更多评论   

是不是因为services.xml里少写了相应的scope配置?
2010-06-15 18:39 | nihao

# re: WebService大讲堂之Axis2(5):会话(Session)管理  回复  更多评论   

在<service>上添加 scope="transportsession" 后就正常了. 确实是services.xml少写了这句造成的.
2010-06-15 19:05 | nihao

# re: WebService大讲堂之Axis2(5):会话(Session)管理[未登录]  回复  更多评论   

有个问题:
按照示例写的WebServices,用Java写的客户端调用,能够成功。但是用C#.net 调用时,调用getLoginMsg获取的内容为null。
难道Axis2里面的Session只能被Java写的客户端使用??
2010-09-01 17:34 | jimmy

# re: WebService大讲堂之Axis2(5):会话(Session)管理  回复  更多评论   

楼主不出来了帮忙了么?
我和楼上同样的问题出现了,谁能指导一下?

另外,我还有二个疑问,我是用的是 scope="application“ :
第一:我 A 客户端 login 后 取值,成功了, B客户端,只做取值,居然把 A客户端设置的值取出来,为什么啊?
第二:session 的失效时间,我该从哪里设定管理呢?
第三:http://blog.csdn.net/tsun7263/archive/2009/10/204705006.aspx 这篇文章翻译了 Axis2的会话管理 。 ” 管理SOAP会话,客户端需要在SOAP头中增加名为“serviceGroupId”的参数。 “ ,我想知道如何给 SOAP头中增加名为“serviceGroupId”的参数。java代码该怎么写?
2010-11-02 17:46 | deadncut

# re: WebService大讲堂之Axis2(5):会话(Session)管理  回复  更多评论   

您好,服务端是.net开发,客户端是JAVA,我自动生成了代码,但
运行到:
MessageContext mc = MessageContext.getCurrentMessageContext();
ServiceContext sc = mc.getServiceContext();
这两句的时候,总是报:
Exception in thread "main" java.lang.NullPointerException
很想知道为什么.我的QQ:30962620
望能答复!
2011-03-13 00:52 | 半导体

# re: WebService大讲堂之Axis2(5):会话(Session)管理  回复  更多评论   

我也是按照你上面的介绍的做了一个服务,可是客户端调用就会出现异常,
<service name="loginService" scope="transportsession">
只有这种情况调用不了。这是为什么呢。其它的都可以调用。唯有这种不可以。
2011-07-05 18:16 | ytwps

# re: WebService大讲堂之Axis2(5):会话(Session)管理  回复  更多评论   

@Sophie
我也是啊,我发布后没找到services.xml文件,自己在META-INF下加了一个services.xml好像不起作用,应该放在哪个目录?
2011-09-15 14:43 | hduwengbin

# re: WebService大讲堂之Axis2(5):会话(Session)管理  回复  更多评论   

我在getLoginMsg方法中加了
System.out.println((String)sc.getProperty("login"));
打印出来结果也是null,应该是services.xml没起作用,我用eclipse插件发布的service 应该去哪个目录设置这个services.xml?
2011-09-15 14:50 | hduwengbin

# re: WebService大讲堂之Axis2(5):会话(Session)管理  回复  更多评论   

LoginService 能够成功发布 但是System.out.println(stub.getLoginMsg().local_return());中getLoginMsg()方法报错 一定要加参数才行加了不知道如何解决
2012-03-27 15:38 | 12

# re: WebService大讲堂之Axis2(5):会话(Session)管理  回复  更多评论   

下面的代码我测试过,能正常运行:
public static void main(String[] args) {
LoginServiceStub stub = null;
try {
stub = new LoginServiceStub();
} catch (AxisFault e) {
e.printStackTrace();
}

LoginServiceStub.Login login = new LoginServiceStub.Login();
login.setUsername("bill");
login.setPassword("1234");
try {
if(stub.login(login).get_return()) {
LoginServiceStub.GetLoginMsg getLoginMsg = new LoginServiceStub.GetLoginMsg();
System.out.println(stub.getLoginMsg(getLoginMsg).get_return());
}
} catch (RemoteException e) {
e.printStackTrace();
}
}

控制台输出是:
成功登录
2012-05-12 10:49 | xiaoqing2305

# re: WebService大讲堂之Axis2(5):会话(Session)管理  回复  更多评论   

@xiaoqing2305
用的是axis2-1.6.1
2012-05-12 11:11 | xiaoqing2305

# axis2-1.6.2 session  回复  更多评论   

axis2-1.6.2 :
if(stub.isLogin(method).get_return()){
System.out.println(stub.getLoginMsg(new MswsStub.GetLoginMsg()).get_return());
}
2012-06-24 17:30 | wen12128

# re: WebService大讲堂之Axis2(5):会话(Session)管理  回复  更多评论   

我发现最后的代码调用有一点小问题:现发出来 供大家参考
LoginServiceStub stub = new LoginServiceStub();
LoginServiceStub.Login login = new LoginServiceStub.Login();
login.setArgs0("bill");
login.setArgs1("1234");

if(stub.login(login).local_return)
{
LoginServiceStub.GetLoginMsg getlm = new GetLoginMsg();
System.out.println(stub.getLoginMsg(getlm).local_return);
}
2012-07-12 10:49 | 风云网络

只有注册用户登录后才能发表评论。


网站导航:
博客园   IT新闻   Chat2DB   C++博客   博问