配色: 字号:
axis2_WebService_开发指南
2012-10-10 | 阅:  转:  |  分享 
  
Axis的简单准备

Axis的入门实例

Axis复杂对象类型的WebService

Axis的辅助工具发布、调用WebService

AxisWebService会话Session的管理

Axis用控制台Dos命令发布WebService

Axis跨多个WebService管理Session

Axis用Spring的JavaBean发布WebService

Axis异步调用WebService

Axis的Module模块

Axis使用SoapMonitar监视WebService的请求和响应信息



Version1.02011-03-15





Axis2.xWebService



上次介绍了axis1.x的用法,这次继续上次的,将叙述axis2的用法。

Axis1.x在线博文:http://www.cnblogs.com/hoojo/archive/2010/12/20/1911349.html



准备工作

1、开发准备

首先需要下载axis2的相关jar包,到axis的官方网站即可获得开发的依赖包。

下载地址:http://axis.apache.org/axis2/java/core/download.cgi

现在最高的版本是1.5.4的

然后你需要下载官方提供的axis的eclipse插件工具,可以帮助我们打包(aar)及其生产客户端调用代码。

下载页面:http://axis.apache.org/axis2/java/core/tools/index.html

ServiceArchiveWizard-EclipsePlug-in

CodeGeneratorWizard-EclipsePlug-in



2、安装eclipse插件

如果你的eclipse插件安装成功后,会看到如下效果:



3、分析axis2-bin文件目录结构

下载下来的axis2的依赖库,其中有一个axis2-1.5.3-bin.zip的库文件,目录结构如下:



bin文件夹是axis2的常用工具,其中有将wsdl文件转换成客户端调用的wsdl2java工具及将java转换成wsdl文件的工具

conf是axis2的配置文件

lib运行所要的依赖库

repository是发布过的axis服务和文件

sample是示例

webapp是web文件和jsp页面等

4、我们需要将下载下来的axis2-1.5.3-war.zip中的axis2.war这个文件放在我们的tomcat目录下,启动tomcat就会把war文件转成一个可以跑起来的axis2的项目。

Tomcat启动后,在浏览器中输入:http://localhost:8080/axis2/你可以看到



Axis2的简单WebService示例

1、编写一个简单的WebService的服务器端代码,代码如下:

importjava.util.Random;



/

function:WebServiceHelloWorld服务示例

@authorhoojo

@createDate2011-1-5下午03:35:06

@fileHelloWorldService.java

@packagecom.hoo.service

@projectAxis2WebService

@bloghttp://blog.csdn.net/IBM_hoojo

@emailhoojo_@126.com

@version1.0

/

publicclassHelloWorldService{

publicStringsayHello(Stringname){

returnname+"say:hello[axis2]";

}



publicintgetAge(inti){

returni+newRandom().nextInt(100);

}

} 注意,上面的HelloWorldService是没有package的。Copy这个类的class文件,放到tomcat目录下的webapps的axis2的WEB-INF目录的pojo文件夹下。如果没有pojo这个目录就手动创建一个一个文件夹。然后在浏览器输入:http://localhost:8080/axis2/

点击Services的链接就可以看到我们手动发布的HelloWorldService了,或者是浏览器地址栏输入:http://localhost:8080/axis2/services/listServices

你就可以看到你刚才粘贴过去的这个WebService了。



点击链接就可以看到wsdl文件的内容了。内容很多,如果你看过axis1.x的介绍就知道wsdl文件的大致结构了。



下面讲解下为什么要将class放在pojo文件夹下。首先我们看看[tomcat_home]/webapps/axis2/WEB-INF/conf/axis2.xml

该文件中有这样一行代码:



.class的后缀文件放在目录pojo目录下。



2、测试这个WebService的方法

复制上面的HelloWorldService的链接地址,然后带上方法名称和参数值即可测试调用是否成功。如下:

http://localhost:8080/axis2/services/HelloWorldService/sayHello?name=jack

http://localhost:8080/axis2/services/HelloWorldService这个是WebService的地址

/sayHello是方法名称,?name=jack是参数名称和值

在浏览器中输入上面的地址后,可以看到如下效果:



可以看到返回值,和方法名称。ns:sayHelloResponse是方法名称,所有的方法名称后都会带上Response,后面的ns当然是当前方法所在的类的包名了,这里没有package就是默认的axis2的域名。

同样,getAge方法,也是一样的调用方法。

http://localhost:8080/axis2/services/HelloWorldService/getAge?i=22

结果如下:





3、下面我们看下客户端调用代码的编写,代码如下:

packagecom.hoo.service;



importjavax.xml.namespace.QName;

importorg.apache.axis2.AxisFault;

importorg.apache.axis2.addressing.EndpointReference;

importorg.apache.axis2.client.Options;

importorg.apache.axis2.rpc.client.RPCServiceClient;



/

function:HelloWorldService客户端调用代码

@authorhoojo

@createDate2011-1-7下午03:55:05

@fileHelloWorldClient.java

@packagecom.hoo.service

@projectAxis2WebService

@bloghttp://blog.csdn.net/IBM_hoojo

@emailhoojo_@126.com

@version1.0

/

publicclassHelloWorldClient{



publicstaticvoidmain(String[]args)throwsAxisFault{

//RPCServiceClient是RPC方式调用

RPCServiceClientclient=newRPCServiceClient();

Optionsoptions=client.getOptions();

//设置调用WebService的URL

Stringaddress="http://localhost:8080/axis2/services/HelloWorldService";

EndpointReferenceepf=newEndpointReference(address);

options.setTo(epf);



/

设置将调用的方法,http://ws.apache.org/axis2是方法

默认(没有package)命名空间,如果有包名

就是http://service.hoo.com包名倒过来即可

sayHello就是方法名称了

/

QNameqname=newQName("http://ws.apache.org/axis2","sayHello");

//指定调用的方法和传递参数数据,及设置返回值的类型

Object[]result=client.invokeBlocking(qname,newObject[]{"jack"},newClass[]{String.class});

System.out.println(result[0]);



qname=newQName("http://ws.apache.org/axis2","getAge");

result=client.invokeBlocking(qname,newObject[]{newInteger(22)},newClass[]{int.class});

System.out.println(result[0]);

}

} 如果你了解或是看过axis1.x的WebService,这里的客户端调用代码比较简单,有部分关键注释,这里就不多加赘述。值得注意的是axis2的WebService客户端调用的返回对象是一个Object的数组,这点和axis1.x有很大不同。我们一般拿数组的第一个值,转换强转即可。



复杂对象类型的WebService

1、这次我们编写复杂点的WebService方法,返回的数据是我们定义属性带getter、setter方法JavaBean,一维数组、二维数组等。

看代码:

importjava.io.File;

importjava.io.FileOutputStream;

importjava.io.IOException;

importjava.util.Random;

importdata.User;



/

function:复杂类型数据的WebService:字节数组、返回一维int数组、二维String数组及自定义JavaBean对象等

@authorhoojo

@createDate2011-1-13下午03:34:52

@fileComplexTypeService.java

@package

@projectAxis2WebService

@bloghttp://blog.csdn.net/IBM_hoojo

@emailhoojo_@126.com

@version1.0

/

publicclassComplexTypeService{



publicStringupload4Byte(byte[]b,intlen){

Stringpath="";

FileOutputStreamfos=null;

try{

Stringdir=System.getProperty("user.dir");

Filefile=newFile(dir+"/"+newRandom().nextInt(100)+".jsp");

fos=newFileOutputStream(file);

fos.write(b,0,len);

path=file.getAbsolutePath();

System.out.println("Filepath:"+file.getAbsolutePath());

}catch(Exceptione){

e.printStackTrace();

}finally{

try{

fos.close();

}catch(IOExceptione){

e.printStackTrace();

}

}

returnpath;

}



publicint[]getArray(inti){

int[]arr=newint[i];

for(intj=0;j
arr[j]=newRandom().nextInt(1000);

}

returnarr;

}



publicString[][]getTwoArray(){

returnnewString[][]{{"中国","北京"},{"日本","东京"},{"中国","上海","南京"}};

}



publicUsergetUser(){

Useruser=newUser();

user.setAddress("china");

user.setEmail("jack@223.com");

user.setName("jack");

user.setId(22);

returnuser;

}

} 上面的WebService服务分别是传递字节完成数据上传,返回一维int数组和二维字符串数组,以及返回UserJavaBean对象。

下面看看UserBean代码:

packagedata;



importjava.io.Serializable;



/

function:UserEntity

@authorhoojo

@createDateDec16,201010:20:02PM

@fileUser.java

@packagecom.hoo.entity

@projectAxisWebService

@bloghttp://blog.csdn.net/IBM_hoojo

@emailhoojo_@126.com

@version1.0

/

publicclassUserimplementsSerializable{

privatestaticfinallongserialVersionUID=677484458789332877L;

privateintid;

privateStringname;

privateStringemail;

privateStringaddress;



//getter/setter



@Override

publicStringtoString(){

returnthis.id+"#"+this.name+"#"+this.email+"#"+this.address;

}

} 值得注意的是这个User对象的package是data,如果是其它的package,你就需要在tomcat目录下的webapps中的axis2的WEB-INF目录下创建一个data目录,和你的User对象的目录保持一致。否则你的WebService将会出现ClassNotFontException异常。然后重启你的tomcat,虽然axis2支持热部署。

2、编写调用上面WebService的客户端代码,代码如下:

packagecom.hoo.service;



importjava.io.File;

importjava.io.FileInputStream;

importjava.io.IOException;

importjavax.xml.namespace.QName;

importorg.apache.axis2.addressing.EndpointReference;

importorg.apache.axis2.client.Options;

importorg.apache.axis2.rpc.client.RPCServiceClient;

importcom.hoo.entity.User;



/

function:复杂类型数据WebService客户端调用代码

@authorhoojo

@createDate2011-1-13下午03:36:38

@fileComplexTypeServiceClient.java

@packagecom.hoo.service

@projectAxis2WebService

@bloghttp://blog.csdn.net/IBM_hoojo

@emailhoojo_@126.com

@version1.0

/

publicclassComplexTypeServiceClient{



publicstaticvoidmain(String[]args)throwsIOException{

RPCServiceClientclient=newRPCServiceClient();

Optionsoptions=client.getOptions();

Stringaddress="http://localhost:8080/axis2/services/ComplexTypeService";

EndpointReferenceepr=newEndpointReference(address);

options.setTo(epr);



QNameqname=newQName("http://ws.apache.org/axis2","upload4Byte");

Stringpath=System.getProperty("user.dir");

Filefile=newFile(path+"/WebRoot/index.jsp");

FileInputStreamfis=newFileInputStream(file);

intlen=(int)file.length();

byte[]b=newbyte[len];

intread=fis.read(b);

//System.out.println(read+"#"+len+"#"+newString(b));

fis.close();

Object[]result=client.invokeBlocking(qname,newObject[]{b,len},newClass[]{String.class});

System.out.println("upload:"+result[0]);



qname=newQName("http://ws.apache.org/axis2","getArray");

result=client.invokeBlocking(qname,newObject[]{3},newClass[]{int[].class});

int[]arr=(int[])result[0];

for(Integeri:arr){

System.out.println("int[]:"+i);

}



qname=newQName("http://ws.apache.org/axis2","getTwoArray");

result=client.invokeBlocking(qname,newObject[]{},newClass[]{String[][].class});

String[][]arrStr=(String[][])result[0];

for(String[]s:arrStr){

for(Stringstr:s){

System.out.println("String[][]:"+str);

}

}



qname=newQName("http://ws.apache.org/axis2","getUser");

result=client.invokeBlocking(qname,newObject[]{},newClass[]{User.class});

Useruser=(User)result[0];

System.out.println("User:"+user);

}

} 上面的代码运行后的结果是:

upload:D:\tomcat-6.0.28\bin\28.jsp

int[]:548

int[]:201

int[]:759

String[][]:中国

String[][]:北京

String[][]:日本

String[][]:东京

String[][]:中国

String[][]:上海

String[][]:南京

User:22#jack#jack@223.com#china



这次我们编辑一个返回User对象、List、Map、User[]的形式,并且用axis2的工具完成发布WebService。不再复制class到axis2的工程目录下。

下面看看服务器端WebService代码:

packagecom.hoo.service;



importjava.util.ArrayList;

importjava.util.HashMap;

importjava.util.List;

importjava.util.Map;

importjava.util.Random;

importcom.hoo.entity.User;



/

function:传递User对象类型的List、Map、User、Array等数据方法的WebService

@authorhoojo

@createDate2011-1-13下午03:50:06

@fileManagerUserService.java

@packagecom.hoo.service

@projectAxis2WebService

@bloghttp://blog.csdn.net/IBM_hoojo

@emailhoojo_@126.com

@version1.0

/

publicclassManagerUserService{



/

function:传递User对象,返回User对象

@authorhoojo

@createDate2011-1-13下午03:54:36

@paramuser

@returnUser

/

publicUsereditUser(Useruser){

user.setId(newRandom().nextInt(100));

returnuser;

}



/

function:返回List<User>的数据类型

@authorhoojo

@createDate2011-1-13下午03:57:19

@paramj

@returnList<User>

/

publicListgetUsers(intj){

Listusers=newArrayList();

for(inti=0;i
Useruser=newUser();

user.setAddress("china");

user.setEmail("hoojo_@126.com");

user.setName("hoojo");

user.setId(22+i);

users.add(user);

}

returnusers;

}



/

function:返回Map<String,User>类型的数据

@authorhoojo

@createDate2011-1-13下午04:03:41

@paramj

@returnMap<String,User>

/

publicMapgetUser4Map(intj){

Mapusers=newHashMap();

for(inti=0;i
Useruser=newUser();

user.setAddress("china");

user.setEmail("amy@223.com");

user.setName("amy");

user.setId(22+i);

users.put("user#"+i,user);

}

returnusers;

}



/

function:返回User的数组数据

@authorhoojo

@createDate2011-1-13下午04:05:23

@paramj

@returnUser[]

/

publicUser[]getUser4Array(intj){

User[]users=newUser[j];

for(inti=0;i
Useruser=newUser();

user.setAddress("china");

user.setEmail("tom@223.com");

user.setName("tom");

user.setId(22+i);

users[i]=user;

}

returnusers;

}

} A、下面用axis2的工具生成aar文件,然后完成发布WebService。

点击工作空间WorkSpace,右键New选择Other



选择Axis2ServiceArchiver,点击Next



然后点击Browser选择你当前的工程的classes目录



点击Next

没有WSDL,选择第一项,点击Next,然后再Next一次



不用设置service.xml,直接Next



最关键一步,填写WebService的Name,设置class路径点击Load你就可以看到当前class的方法



勾中的方法表示将会被暴露到客户端可以调用的方法,然后点击Next

设置aar文件的名称和保持的目录



点击Finish你可以看到提示successfully的提示。

刷新当前工程可以看到ManangerUserService.aar文件了



下面我们在浏览器中访问这个地址:http://localhost:8080/axis2/



点击Admin这个链接,可以看到要输入用户名和密码,用户名和密码在

Tomcat_Home\webapps\axis2\WEB-INF\conf下的axis2.xml中可以找到

admin

axis2

输入密码进入管理页面后可以看到



下面介绍下上面常用的功能

UploadService当然是上传aar的文件,完成发布WebService的工具了

AvailableService是查看当前发布的Service详细信息

AvailableServiceGroups是Service组

GlobalChains是可以用的全局的Chain

OperationSpecificChains是某个具体操作的chain

DeactivateService是取消某个Service

ActivateService是将取消发布的Service再发布出去

EditParameters是修改WebService类的参数

我们这里用UploadService这个工具,然后选择我们刚才用axis2的工具生成aar文件。



其实这一步我们可以直接将ManagerUserService.aar文件copy到

tomcat-home\webapps\axis2\WEB-INF\services这个目录下。

然后点击AvailableService就可以看到ManagerUserService这个Service了



B、现在我们要用axis2的工具生成wsdl文件

1、点击WorkSpace,右键New选择Other。然后选择客户端代码生成工具



2、点击Next,你可以看到让你选择wsdl。选择第一个,然后点击Next



上面是根据Javaclass代码生成wsdl文件

3、填写你的WebService的classpath,然后选择你当前class所在工程的class目录



然后点击AddFolder选择你的工程的classes或bin目录,也就是你填写的class所在的目录,然后点击Test测试是否正确。



点击Next继续下一步

4、可以看到即将发布的WebService名称和命名空间



5、继续Next,选择wsdl文件保存目录



这样services.wsdl文件就生成了。

C、用axis2的工具生成客户端调用的代码

1、右键workspace,点击New选择Other,然后选择aixs2的生成代码工具



2、选择第一项,根据wsdl文件生成Java代码,然后Next



3、然后选择刚才上面生成好的wsdl文件



如果你有向tomcat中发布过你的WebService,那么你可以通过WebBrowser访问

http://localhost:8080/axis2/

点击Services链接,就可以看到你的WebService。点击你的WebService



样你也可以看到wsdl内容



这样你也可以在上面的WSDLfilelocation中填写:



http://localhost:8080/axis2/services/ManagerUser?wsdl

这个地址也是可以的

4、点击Next,就可以看到你要生成指定方法的代码的选项了



注意的是在选择PortName的时候,不同的选项将会生产不同的调用代码。其调用方式也略有不同。但你可以看生成的源代码进行详细的了解。

5、点击Next,选择代码输出保存的目录,然后点击Finish



刷新目录后发现多了2个文件



编写客户端代码

packagecom.hoo.service;



importjava.rmi.RemoteException;

importcom.hoo.service.ManagerUserStub.EditUserResponse;



/

function:ManagerUserService客户端调用代码

@authorhoojo

@createDate2011-1-14下午03:17:31

@fileManagerUserServiceClient.java

@packagecom.hoo.service

@projectAxis2WebService

@bloghttp://blog.csdn.net/IBM_hoojo

@emailhoojo_@126.com

@version1.0

/

publicclassManagerUserServiceClient{



publicstaticvoidmain(String[]args)throwsRemoteException{

Stringtarget="http://localhost:8080/axis2/services/ManagerUser";

ManagerUserStubstub=newManagerUserStub(target);



/

调用UserBean模式:

EditUser、User是内部静态类,axis2会帮我们进行参数封装

/

ManagerUserStub.EditUsereditUser=newManagerUserStub.EditUser();

ManagerUserStub.Useru=newManagerUserStub.User();

u.setAddress("china");

u.setEmail("axis2@axis2.com");

u.setName("axis2");

u.setId(222);

editUser.setUser(u);

//返回值也被封装

EditUserResponseeur=stub.editUser(editUser);

ManagerUserStub.UserreturnUser=eur.get_return();

//returnUser.getId()在服务器端动态重置过

System.out.println(returnUser.getId()+"#"+returnUser.getName()+"#"+returnUser.getEmail()+"#"+returnUser.getAddress());



/

User数组模式

/

ManagerUserStub.GetUser4ArrayuserArray=newManagerUserStub.GetUser4Array();

userArray.setJ(3);

ManagerUserStub.GetUser4ArrayResponseuserArrResponse=stub.getUser4Array(userArray);

ManagerUserStub.User[]userArr=userArrResponse.get_return();

for(ManagerUserStub.Useruser:userArr){

System.out.println(user.getId()+"#"+user.getName()+"#"+user.getEmail()+"#"+user.getAddress());

}





/

MapUser模式,不支持Map、List

/

/ManagerUserStub.GetUser4MapuserMap=newManagerUserStub.GetUser4Map();

userMap.setJ(3);

ManagerUserStub.GetUser4MapResponseuserMapResponse=stub.getUser4Map(userMap);

ManagerUserStub.Mapmap=userMapResponse.get_return();

System.out.println(map);/



/

GetUsers是ManagerUserStub的内部类,axis2的代码生成工具会帮我们把参数更具wsdl文件的内容进行封装

/

/ManagerUserStub.GetUsersgetUsers=newManagerUserStub.GetUsers();

getUsers.setJ(3);//服务器的参数intj

ManagerUserStub.GetUsersResponseusersResponse=stub.getUsers(getUsers);

System.out.println(usersResponse.get_return());/

}

} 运行后发现不支持Map、List,不能读取数据类型。Wsdl文件中是anyType,可能需要自己用配置描述返回类型。【有待跟进、解决】

下面用MyEclipse的WebService工具生成代码





WebService会话Session的管理

1、新建Session的WebService测试代码,代码很简单。就是记录用户登录的状态信息,放在MessageContext的ServiceContext中。代码如下:

packagecom.hoo.service;



importorg.apache.axis2.context.MessageContext;

importorg.apache.axis2.context.ServiceContext;



/

function:WebServiceSession会话消息

@authorhoojo

@createDate2011-3-8下午04:11:27

@fileLoginService.java

@packagecom.hoo.service

@projectAxis2WebService

@bloghttp://blog.csdn.net/IBM_hoojo

@emailhoojo_@126.com

@version1.0

/

publicclassLoginService{

publicbooleanlogin(StringuserName,Stringpassword){

MessageContextcontext=MessageContext.getCurrentMessageContext();

ServiceContextctx=context.getServiceContext();

if("admin".equals(userName)&&"123456".equals(password)){

ctx.setProperty("userName",userName);

ctx.setProperty("password",password);

ctx.setProperty("msg","登陆成功");

returntrue;

}

ctx.setProperty("msg","登陆失败");

returnfalse;

}



publicStringgetLoginMessage(){

MessageContextcontext=MessageContext.getCurrentMessageContext();

ServiceContextctx=context.getServiceContext();

returnctx.getProperty("userName")+"#"+ctx.getProperty("msg");

}

} 这里保存Session信息的主要是通过MessageContext这个上下文来获取ServiceContext的上下文,然后通过setProperty来保存session的信息,通过getProperty来获取session信息。

Session的作用可以在使用WebService登录的时候,保存用户的登录状态或是会话消息。但是使用session需要设置发布Service的时候,设置WebService的作用域。作用域默认是request,它还有另外三个值,分别是:application、soapsession、transportsession;我们可以选择使用transportsession和application分别实现同一个WebService类和跨WebService类的会话管理。

2、使用axis2的工具生成aar文件,并发布LoginService服务。



关于这里发布LoginService的步骤就不一一介绍,上面已经有说过了。当你用这个步骤发布WebService的时候,你可以打开压缩文件的方式aar文件(其实不一定要用aar文件,只是官方推荐的aar,jar文件也是可以的),在META-INF目录下有一个services.xml文件,看到它的这个标签,没有设置scope属性。



scope默认的是request,我们得修改services.xml的内容。

修改后services.xml内容如下:





PleaseTypeyourservicedescriptionhere






class="org.apache.axis2.rpc.receivers.RPCInOnlyMessageReceiver"/>


class="org.apache.axis2.rpc.receivers.RPCMessageReceiver"/>



com.hoo.service.LoginService

这个地方的scope是关键,如果这里不设置的话session是无法存放信息。

3、用控制台Dos命令发布WebService

这个是手工打包,也就是我们经常用的jar命令

首先我们得需要一个services.xml文件,文件内容如上面的。



name是当前发布WebService的名称,scope是会话作用域。保存在Session中就要用这个transportsession这个作用域。

com.hoo.service.LoginService

这个是当前Service的类路径,包名+类名




class="org.apache.axis2.rpc.receivers.RPCInOnlyMessageReceiver"/>


class="org.apache.axis2.rpc.receivers.RPCMessageReceiver"/>



这个应该是参数和返回值信息的解析类,in-only是输入也就是参数,in-out是输出也就是返回值。

首先,我们在C盘下新建一个sessionService的目录,然后将上面的services.xml文件中的ServiceClass的类的class文件copy到这个目录下,注意要带上package目录,然后在sessionService目录下新建一个META-INF将上面的services.xml文件放到这个目录下

然后运行cmd进入控制台,进入sessionService这个目录,键入命令如下:

jarcvfservice.aar



service.aar是打包后的文件名称,.是指代当前目录

如果你不懂jar命令,你可以输入jar会有命令语法的提示



进入sessionService这个目录中,你可以看到service.aar文件就有了。然后将这个文件copy到axis2的WEB-INF目录下的services目录中,也就是

[tomcat-home]\webapps\axis2\WEB-INF\services

然后可以通过:http://localhost:8080/axis2/services/listServices

就可以查看刚才发布的服务了。

这样就完成手工发布打包发布WebService了

编写WebService客户端的请求代码

packagecom.hoo.service;



importjavax.xml.namespace.QName;

importorg.apache.axis2.AxisFault;

importorg.apache.axis2.addressing.EndpointReference;

importorg.apache.axis2.client.Options;

importorg.apache.axis2.rpc.client.RPCServiceClient;



/

function:LoginServiceSession客户端代码

@authorhoojo

@createDate2011-3-9上午11:21:59

@fileLoginServiceClient.java

@packagecom.hoo.service

@projectAxis2WebService

@bloghttp://blog.csdn.net/IBM_hoojo

@emailhoojo_@126.com

@version1.0

/

publicclassLoginServiceClient{



publicstaticvoidmain(String[]args)throwsAxisFault{

Stringtarget="http://localhost:8080/axis2/services/LoginService";

//target="http://localhost:8080/axis2/services/MyLoginService";

RPCServiceClientclient=newRPCServiceClient();

Optionsoptions=client.getOptions();

options.setManageSession(true);



EndpointReferenceepr=newEndpointReference(target);

options.setTo(epr);



QNameqname=newQName("http://service.hoo.com","login");

//指定调用的方法和传递参数数据,及设置返回值的类型

Object[]result=client.invokeBlocking(qname,newObject[]{"admin","123456"},newClass[]{boolean.class});

System.out.println(result[0]);



qname=newQName("http://service.hoo.com","getLoginMessage");

result=client.invokeBlocking(qname,newObject[]{null},newClass[]{String.class});

System.out.println(result[0]);

}

} 执行后,结果如下:

true

admin#登陆成功

options.setManageSession(true);是开启对Session管理的支持

跨多个WebService管理Session

当多个WebService的时候,我们要管理它的Session。这个时候我们得依靠ServiceGroupContext保存session信息;然后在发布WebService的时候,services.xml文件的的service表情的scope就不再说request或是transportsession了,而是application;最后同样要开启对session的管理,即options.setManageSession(true);

首先多个WebService的session管理的代码如下:

packagecom.hoo.service;



importorg.apache.axis2.context.MessageContext;

importorg.apache.axis2.context.ServiceGroupContext;



/

function:管理多个会话Session信息

@authorhoojo

@createDate2011-3-9下午05:11:07

@fileLoginSessionService.java

@packagecom.hoo.service

@projectAxis2WebService

@bloghttp://blog.csdn.net/IBM_hoojo

@emailhoojo_@126.com

@version1.0

/

publicclassLoginSessionService{

publicbooleanlogin(StringuserName,Stringpassword){

MessageContextcontext=MessageContext.getCurrentMessageContext();

ServiceGroupContextctx=context.getServiceGroupContext();

if("admin".equals(userName)&&"123456".equals(password)){

ctx.setProperty("userName",userName);

ctx.setProperty("password",password);

ctx.setProperty("msg","登陆成功");

returntrue;

}

ctx.setProperty("msg","登陆失败");

returnfalse;

}



publicStringgetLoginMessage(){

MessageContextcontext=MessageContext.getCurrentMessageContext();

ServiceGroupContextctx=context.getServiceGroupContext();

returnctx.getProperty("userName")+"#"+ctx.getProperty("msg");

}

} 和上面的Session一样的操作,只不过是用ServiceGroupContext上下文来存取session信息

另外还需要用一个Service来查询session的信息,SearchService的代码如下:

packagecom.hoo.service;



importorg.apache.axis2.context.MessageContext;

importorg.apache.axis2.context.ServiceGroupContext;



/

function:查找多服务Session会话中的消息

@authorhoojo

@createDate2011-3-9下午05:22:39

@fileSearchSessionServcie.java

@packagecom.hoo.service

@projectAxis2WebService

@bloghttp://blog.csdn.net/IBM_hoojo

@emailhoojo_@126.com

@version1.0

/

publicclassSearchSessionServcie{

publicStringfindSessionMessage(Stringkey){

MessageContextmc=MessageContext.getCurrentMessageContext();

ServiceGroupContextctx=mc.getServiceGroupContext();

if(ctx.getProperty(key)!=null){

return"找到的数据<"+key+","+ctx.getProperty(key)+">";

}else{

return"没有找到<"+key+">的数据";

}

}

} 编写services.xml来发布这2个服务,还以前不一样的。这一次是用一个services.xml文件配置2个service,同时发布2个服务。Xml代码如下:







WebServiceSession例子





com.hoo.service.LoginSessionService






class="org.apache.axis2.rpc.receivers.RPCMessageReceiver"/>


class="org.apache.axis2.rpc.receivers.RPCInOnlyMessageReceiver"/>











WebServiceSearchSession例子





com.hoo.service.SearchSessionServcie






class="org.apache.axis2.rpc.receivers.RPCMessageReceiver"/>


class="org.apache.axis2.rpc.receivers.RPCInOnlyMessageReceiver"/>





发布完成后,可以通过http://localhost:8080/axis2/services/listServices查看发布的WebService服务,编写客户端的测试代码,code如下:

packagecom.hoo.service;



importjavax.xml.namespace.QName;

importorg.apache.axis2.AxisFault;

importorg.apache.axis2.addressing.EndpointReference;

importorg.apache.axis2.client.Options;

importorg.apache.axis2.rpc.client.RPCServiceClient;



/

function:多会话Session管理,WebService客户端请求代码

@authorhoojo

@createDate2011-3-9下午05:17:15

@fileLoginSessionServiceClient.java

@packagecom.hoo.service

@projectAxis2WebService

@bloghttp://blog.csdn.net/IBM_hoojo

@emailhoojo_@126.com

@version1.0

/

publicclassLoginSessionServiceClient{



publicstaticvoidmain(String[]args)throwsAxisFault{

Stringtarget="http://localhost:8080/axis2/services/LoginSessionService";

RPCServiceClientclient=newRPCServiceClient();

Optionsoptions=client.getOptions();

options.setManageSession(true);



EndpointReferenceepr=newEndpointReference(target);

options.setTo(epr);



QNameqname=newQName("http://service.hoo.com","login");

//指定调用的方法和传递参数数据,及设置返回值的类型

Object[]result=client.invokeBlocking(qname,newObject[]{"admin","123456"},newClass[]{boolean.class});

System.out.println(result[0]);



qname=newQName("http://service.hoo.com","getLoginMessage");

result=client.invokeBlocking(qname,newObject[]{null},newClass[]{String.class});

System.out.println(result[0]);



target="http://localhost:8080/axis2/services/SearchSessionService";

epr=newEndpointReference(target);

options.setTo(epr);



qname=newQName("http://service.hoo.com","findSessionMessage");

result=client.invokeBlocking(qname,newObject[]{"userName"},newClass[]{String.class});

System.out.println(result[0]);

qname=newQName("http://service.hoo.com","findSessionMessage");

result=client.invokeBlocking(qname,newObject[]{"msg"},newClass[]{String.class});

System.out.println(result[0]);



qname=newQName("http://service.hoo.com","findSessionMessage");

result=client.invokeBlocking(qname,newObject[]{"password"},newClass[]{String.class});

System.out.println(result[0]);

}

} 运行后结果如下:

true

admin#登陆成功

找到的数据

找到的数据

找到的数据

的内容改成scope=transportsession,看看什么情况。是不是找不到session中的内容。

用Spring创建的JavaBean发布成WebService

1、首先,看看这个简单的类代码:

packagecom.hoo.service;



/

function:Spring的装载Bean的Service

@authorhoojo

@createDate2011-3-9下午06:30:26

@fileSpringService.java

@packagecom.hoo.service

@projectAxis2WebService

@bloghttp://blog.csdn.net/IBM_hoojo

@emailhoojo_@126.com

@version1.0

/

publicclassSpringService{

privateStringname;

privateintnumber;



publicvoidsetName(Stringname){

this.name=name;

}



publicvoidsetNumber(intnumber){

this.number=number;

}



publicStringgetMessage(){

returnthis.number+"#"+this.name;

}

} 将这个类编译后的class,放到[tomcat-home]\webapps\axis2\WEB-INF\classes中,注意带上package类路径的目录。

2、在\webapps\axis2\WEB-INF\web.xml文件中加入下面的内容:



org.springframework.web.context.ContextLoaderListener





contextConfigLocation

classpath:applicationContext.xml

这段配置会Spring的朋友肯定知道,这个是加载spring容器和设置spring的配置文件的。

3、在[tomcat-home]\webapps\axis2\WEB-INF\classes中新建一个applicationContext.xml文件,文件中的内容如下:




xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"

xsi:schemaLocation="http://www.springframework.org/schema/beans

http://www.springframework.org/schema/beans/spring-beans-2.5.xsd">









上面配置了SpringService,利用Spring的容器帮我们设置name、number这2个属性的值。

在tomcat-home\webapps\axis2\WEB-INF\lib目录中有一个axis2-spring-1.5.3.jar文件,该文件用于将被装配JavaBean的发布成WebService。同样这里我们采用手动打包发布的模式,在C盘建立一个axis2-spring-ws的目录,然后在此目录中新建一个META-INF的目录,目录中添加一个services.xml文件,内容如下:





Springaware





org.apache.axis2.extensions.spring.receivers.SpringServletContextObjectSupplier







SpringBeanService






class="org.apache.axis2.rpc.receivers.RPCMessageReceiver"/>



在文件中需要通过ServiceObjectSupplier参数指定SpringServletContextObjectSupplier类来获得Spring的ApplicationContext对象;

然后用jar命令创建aar文件



然后将生产的aar文件,复制到[tomcat_home]\webapps\axis2\WEB-INF\services目录中

然后重启tomcat,访问:

http://localhost:8080/axis2/services/listServices

就可以看到刚才发布的springService了



编写客户端测试代码

packagecom.hoo.service;



importjavax.xml.namespace.QName;

importorg.apache.axis2.AxisFault;

importorg.apache.axis2.addressing.EndpointReference;

importorg.apache.axis2.client.Options;

importorg.apache.axis2.rpc.client.RPCServiceClient;



/

function:SpringService客户端代码

@authorhoojo

@createDate2011-3-14上午14:21:59

@fileLoginServiceClient.java

@packagecom.hoo.service

@projectAxis2WebService

@bloghttp://blog.csdn.net/IBM_hoojo

@emailhoojo_@126.com

@version1.0

/

publicclassSpringServiceClient{



publicstaticvoidmain(String[]args)throwsAxisFault{

Stringtarget="http://localhost:8080/axis2/services/springService";

RPCServiceClientclient=newRPCServiceClient();

Optionsoptions=client.getOptions();

options.setManageSession(true);



EndpointReferenceepr=newEndpointReference(target);

options.setTo(epr);



QNameqname=newQName("http://service.hoo.com","getMessage");

Object[]result=client.invokeBlocking(qname,newObject[]{null},newClass[]{String.class});

System.out.println(result[0]);

}

} 运行后,看到bean注入的值有输出。

1#hoojo 异步调用WebService

异步,说到异步需要首先将以下同步。同步就是代码按照顺序执行,当前面的代码的请求没有正常返回结果的情况下,后面的代码是不能运行。而异步正好和这点不同,异步是代码运行后,不管当前的请求是否返回结果,后面的代码都会继续运行。

关于异步在此就不再赘述了,有兴趣的可以去网上查查这方面的资料。

编写服务器端的代码。

packagecom.hoo.service;



/

function:异步WebService服务器端代码

@authorhoojo

@createDate2011-3-14上午08:16:59

@fileAsynchronousService.java

@packagecom.hoo.service

@projectAxis2WebService

@bloghttp://blog.csdn.net/IBM_hoojo

@emailhoojo_@126.com

@version1.0

/

publicclassAsynchronousService{

publicStringexecute(){

System.out.println("正在执行此代码……");

//延迟5秒后,返回结果

try{

Thread.sleep(5000);

}catch(InterruptedExceptione){

e.printStackTrace();

}

return"完成";

}

} tomcat-home]\webapps\axis2\WEB-INF\services目录下

services.xml





AsyncService





com.hoo.service.AsynchronousService






class="org.apache.axis2.rpc.receivers.RPCMessageReceiver"/>


class="org.apache.axis2.rpc.receivers.RPCInOnlyMessageReceiver"/>



编写客户端测试代码

packagecom.hoo.service;



importjava.io.IOException;

importjavax.xml.namespace.QName;

importorg.apache.axis2.addressing.EndpointReference;

importorg.apache.axis2.client.Options;

importorg.apache.axis2.client.async.AxisCallback;

importorg.apache.axis2.context.MessageContext;

importorg.apache.axis2.rpc.client.RPCServiceClient;



/

function:异步WebService客户端代码

@authorhoojo

@createDate2011-3-14上午09:00:03

@fileAsynchronousServiceClient.java

@packagecom.hoo.service

@projectAxis2WebService

@bloghttp://blog.csdn.net/IBM_hoojo

@emailhoojo_@126.com

@version1.0

/

publicclassAsynchronousServiceClient{



publicstaticvoidmain(String[]args)throwsIOException{

Stringtarget="http://localhost:8080/axis2/services/AsyncService?wsdl";

RPCServiceClientclient=newRPCServiceClient();

Optionsoptions=client.getOptions();

options.setManageSession(true);



EndpointReferenceepr=newEndpointReference(target);

options.setTo(epr);



QNameqname=newQName("http://service.hoo.com","execute");

//指定调用的方法和传递参数数据,及设置返回值的类型

client.invokeNonBlocking(qname,newObject[]{},newAxisCallback(){



publicvoidonMessage(MessageContextctx){

System.out.println(ctx.getEnvelope());

System.out.println("Message:"+ctx.getEnvelope().getFirstElement().getFirstElement().getFirstElement().getText());

}



publicvoidonFault(MessageContextctx){

}



publicvoidonError(Exceptionex){

}



publicvoidonComplete(){

}

});

System.out.println("异步WebService");

//阻止程序退出

System.in.read();

}

} 上面是异步调用WebService的代码,调用的方法是client.invokeNonBlocking,这个方法有三个参数,参数一是执行的方法签名,参数二是执行该方法的参数,参数三是异步回调,这里隐式实现AxiaCallback接口

注意的是运行程序的时候要用Debug方式运行。

编写Module模块

Axis可以通过Module模块进行扩展,用户可以编写定制自己的Module模块。编写一个Module的模块至少需要实现两个接口,分别是Handler和Module接口。开发axis2的Module模块需要如下步骤:

实现Module接口的实现类,这个类要完成基本的初始化、销毁等操作

实现Handler接口的实现类,这个类主要是完成业务处理

在META-INF目录下,创建module.xml配置文件

在axis2.xml中增加配置module的模块

在services.xml中增加module的模块配置

最后发表axis2的module模块,需要用jar命令将工程打包成mar,然后将mar文件发布到[tomcat_home]/webapps/axis2/WEB-INF/modules目录下;



首先编写一个简单的WebService,代码如下:

packagecom.hoo.module;



importjava.util.Random;



/

function:编写一个简单的WebService服务器端代码

@authorhoojo

@createDate2011-3-15上午06:19:15

@fileSimpleWebService.java

@packagecom.hoo.module

@projectAxis2WebService

@bloghttp://blog.csdn.net/IBM_hoojo

@emailhoojo_@126.com

@version1.0

/

publicclassSimpleWebService{

publicintrandInt(){

returnnewRandom().nextInt(100);

}

} 编写Module接口的实现类,代码如下:

packagecom.hoo.module;



importorg.apache.axis2.AxisFault;

importorg.apache.axis2.context.ConfigurationContext;

importorg.apache.axis2.description.AxisDescription;

importorg.apache.axis2.description.AxisModule;

importorg.apache.axis2.modules.Module;

importorg.apache.neethi.Assertion;

importorg.apache.neethi.Policy;



/

function:axis2模块,实现Module接口实现类

@authorhoojo

@createDate2011-3-15上午03:22:24

@fileCustomModule.java

@packagecom.hoo.module

@projectAxis2WebService

@bloghttp://blog.csdn.net/IBM_hoojo

@emailhoojo_@126.com

@version1.0

/

publicclassCustomModuleimplementsModule{



publicvoidapplyPolicy(Policypolicy,AxisDescriptionaxisDescription)throwsAxisFault{

System.out.println("###############applyPolicy##############");

}



publicbooleancanSupportAssertion(Assertionassertion){

System.out.println("##############canSupportAssertion##############");

returntrue;

}



publicvoidengageNotify(AxisDescriptionaxisDescription)throwsAxisFault{

System.out.println("##############engageNotify#############");

}



publicvoidinit(ConfigurationContextctx,AxisModulemodule)throwsAxisFault{

System.out.println("##############init##############");

}



publicvoidshutdown(ConfigurationContextctx)throwsAxisFault{

System.out.println("##############shutdown#############");

}

} 编写实现Handler接口的实现类,代码如下:

packagecom.hoo.module;



importorg.apache.axis2.AxisFault;

importorg.apache.axis2.context.MessageContext;

importorg.apache.axis2.description.HandlerDescription;

importorg.apache.axis2.description.Parameter;

importorg.apache.axis2.engine.Handler;



/

function:axis2模块Handler接口实现

@authorhoojo

@createDate2011-3-15上午03:37:43

@fileCustomHandler.java

@packagecom.hoo.module

@projectAxis2WebService

@bloghttp://blog.csdn.net/IBM_hoojo

@emailhoojo_@126.com

@version1.0

/

publicclassCustomHandlerimplementsHandler{



privateStringname;



publicvoidsetName(Stringname){

this.name=name;

}



publicStringgetName(){

returnthis.name;

}



publicvoidcleanup(){

System.out.println("###########cleanup###########");

}



publicvoidflowComplete(MessageContextctx){

System.out.println("###########flowComplete###########");

System.out.println(ctx.getEnvelope().toString());

}



publicHandlerDescriptiongetHandlerDesc(){

System.out.println("###########getHandlerDesc###########");

returnnull;

}



publicParametergetParameter(Stringname){

System.out.println("###########getParameter###########");

returnnull;

}



publicvoidinit(HandlerDescriptionhandlerDescription){

System.out.println("###########init###########");

}



publicInvocationResponseinvoke(MessageContextctx)throwsAxisFault{

System.out.println(ctx.getEnvelope().toString());

returnInvocationResponse.CONTINUE;

}

} 编写module.xml文件















































编写services.xml文件



使用CustomModuleSimpleWebService模块







com.hoo.module.SimpleWebService






class="org.apache.axis2.rpc.receivers.RPCMessageReceiver"/>


class="org.apache.axis2.rpc.receivers.RPCInOnlyMessageReceiver"/>



在[tomcat_home]\webapps\axis2\WEB-INF\conf中axis2.xml文件中加入内容,在所有的标签中加入

打包发布module,在c盘建立CustomModuleService,然后将CustomModule.class和CustomHandler.class以及类路径目录复制到该目录。然后将module.xml文件放到META-INF(没有新建)目录。

运行jar命令:jarcvfcustom-module.mar.

将生成的custom-module.mar文件粘贴到[tomcat_home]\webapps\axis2\WEB-INF\modules目录中

发布WebService,建立目录simpleWebService,将SimpleWebService.xml和类路径复制到该目录下,将services.xml复制到META-INF目录。

运行jar命令:jarcvfsimple-service.aar.

将生成的simple-service.aar文件复制到[tomcat_home]\webapps\axis2\WEB-INF\services目录下

然后重启tomcat服务。

客户端访问WebService代码

packagecom.hoo.service;



importjavax.xml.namespace.QName;

importorg.apache.axis2.AxisFault;

importorg.apache.axis2.addressing.EndpointReference;

importorg.apache.axis2.client.Options;

importorg.apache.axis2.rpc.client.RPCServiceClient;



/

function:访问SimpleWebService

@authorhoojo

@createDate2011-3-15上午07:26:08

@fileSimpleWebServiceClient.java

@packagecom.hoo.service

@projectAxis2WebService

@bloghttp://blog.csdn.net/IBM_hoojo

@emailhoojo_@126.com

@version1.0

/

publicclassSimpleWebServiceClient{



publicstaticvoidmain(String[]args)throwsAxisFault{

Stringtarget="http://localhost:8080/axis2/services/CustomModuleService";

RPCServiceClientclient=newRPCServiceClient();

Optionsoptions=client.getOptions();

options.setManageSession(true);



EndpointReferenceepr=newEndpointReference(target);

options.setTo(epr);



QNameqname=newQName("http://module.hoo.com","randInt");

Object[]result=client.invokeBlocking(qname,newObject[]{null},newClass[]{int.class});

System.out.println(result[0]);

}

}

使用SoapMonitar监视WebService的请求和响应信息

使用soapmonitar可以监视到请求和响应的WebService的基本信息,可以讲响应在控制台的信息显示在applet控件上。

步骤如下:

部署相关的applet和servlet

Axis2有自带的monitor模块,这里就不需要单独安装。在[tomcat_home]\webapps\axis2\WEB-INF\lib目录中,找到axis2-soapmonitor-servlet-1.5.3.jar这个文件,将这个文件解压后,将里面的servlet的class文件放到[tomcat_home]\webapps\axis2\WEB-INF\classes目录下。将applet的class放到[tomcat_home]\webapps\axis2这个目录下即可。

配置Servlet,这里配置的Servlet就包含上一步复制的servlet-class

在web.xml中增加如下配置



SOAPMonitorService

org.apache.axis2.soapmonitor.servlet.SOAPMonitorService



SOAPMonitorPort

5001



1







SOAPMonitorService

/SOAPMonitor



在要监视的WebService的services.xml文件中关联soapmonitor,services.xml配置文件如下:



使用soapmonitorSimpleWebService模块







com.hoo.module.SimpleWebService






class="org.apache.axis2.rpc.receivers.RPCMessageReceiver"/>


class="org.apache.axis2.rpc.receivers.RPCInOnlyMessageReceiver"/>



将上次的WebService关联soapmonitor这个module,然后重新打包aar发布。

请求http://localhost:8080/axis2/SOAPMonitor

可以看到Java的Applet,界面如下:



然后运行请求执行CustomModuleService这个service的时候,你就可一看到上面出现xml的内容。上面的内容是和控制台的同步输出的。



44 AxisWebService技术指南



欢迎转载请保留原文作者信息不得未经作者允许用于商业用途

















Axis2.xWebService开发指南





hoojo

授之以鱼,不如授之以渔!希望能给广大IT朋友带来一些帮助





IT达人

自由IT职业

blog.csdn.net/IBM_hoojohttp://hoojo.cnblogs.com/

506637315

2011-3-15







献花(0)
+1
(本文系Micon_lee首藏)