axis2 基础介绍

1.AXIS2 简介:

Apache Axis2 项目是一个基于 Java 语言的 Web services 系统服务和客户端的实现。为了从 Apache Axis 1.0 中获取教训, Apache Axis2 提供了一个完整的对象模型和模块化体系结构,这样可以很容易的添加功能以及支持一个新的与 Web services 相关的说明和建议。 Axis2 可以让你很容易的执行以下任务:

(1). 发送 SOAP 消息。

(2). 接收和处理 SOAP 消息。

(3). 从一个普通的 Java 类建立 Web service

(4). WSDL 来建立实现服务和客户端的实现类。

(5). 很容易的从一个服务来获取 WSDL

(6). 发送和接收带有附件的 SOAP 消息。

(7). 建立或者使用基于 REST Web service

(8). 建立或者使用从 WS-Security WS-ReliableMessaging WS-Addressing WS-Coordination WS-Atomic Transaction 获取优势的服务。

(9). 当新建议出现时,使用 Axis2 的模块化结构来很容易的加入对它的支持。

2. 配置 AXIS2 环境:

(1). 下载 Axis2 ,去 http://ws.apache.org/axis2/ 下载 axis2 的最新版本,一般是两个 zip 文件,如 axis2-1.4.1-bin.zip( 包含了 Axis2 中所有的 jar 文件 ) axis2-1.4.1-war.zip( 用于将 WebService 发布到 web 容器中 )
(2). 
axis2-1.4.1-war.zip 解压,将目录中的 axis2.war 文件放到 Servlet 容器的项目发布目录中,以 Tomcat 为例,放到 ”%Tomcat%/webapps” 目录中,启动 Tomcat

(3). 在浏览器地址栏中输入如下的 URL http://localhost:8080/axis2/ ,应该可以进入 axis2 的欢迎界面,点击 ”Validate” 如果没有报错,则说明 axis2 的环境已经配置好。

(4). 点击 ”Administration” ,初始用户名和密码分别是: admin axis2 ,也可以到 ” %Tomcat%/webapps/axis2/WEB-INF/conf/axis2.xml” 下修改用户名和密码。

3.POJO 发布成 AXIS2 WebService 的简单例子:

(1). 编程普通的 java 类,将编译过后的 ”.class” 文件拷贝到 axis2 POJO 发布目录 ”%Tomcat%/webapps/axis2/WEB-INF/POJO” 中。
注意:若目录下没有 POJO 目录,则手动新建该目录即可。

(2). 启动 Tomcat POJO 即被发布成了 WebService java 类中中所有的 public 方法即被发布成 WebService Operation

注意: POJO 类不能使用 package 关键字声明包, AXIS2 默认是热部署的。

4.POJO 无配置发布高级:

由于 AXIS2 POJO 发布方式不支持 Package ,若类中需要调用其他类的方法时,需要将所引用的类编译后的 ”.class” 文件拷贝到 ”%Tomcat%/webapps/axis2/WEB-INF/classes” 目录下。

5.AXIS2 客户端的简单实现:

(1). 使用 RPC 方式调用 WebService

[java]   view plain copy
  1. RPCServiceClient client =  new  RPCServiceClient();  
  2. Options options = client.getOptions();  
 

(2). 指定调用 WebService URL

[java]   view plain copy
  1. EndpointReference targetURL =  new  EndpointReference(“WebService发布的URL地址”);  
  2. Options.setTo(targetURL);  
 

(3). 指定调用服务方法的参数值:

[java]   view plain copy
  1. Object[] parameters =  new  Object[]{参数值};  
 

(4). 指定方法返回值的数据类型,如:

[java]   view plain copy
  1. Class[] classes =  new  Class[]{String. class };  
 

(5). 指定要调用方法名和 WSDL 文件的命名空间:

[java]   view plain copy
  1. //命名空间为wsdl文件中<wsdl:definitions>元素的targetNamespace属性值   
  2. QName qname = new  QName(“命名空间”, “调用方法名”);  
 

(6). 调用服务的方法:

[java]   view plain copy
  1. //三个参数第一个为QName对象,表示要调用的方法名;第二个参数表示要调用的//WebService方法的参数值;第三个参数表示WebService方法的返回值类型   
  2. Object result = client.invokeBlocking(qname, parameters, classes)[0 ];  
 

注意:当方法没有参数时,第二个参数值不能为 null ,而要使用 new Object[]{}

当被调用的方法没有返回值时,应该使用 RPCServiceClient 类的 invokeRobust 方法。

6. 使用 wsdl2java 简化客户端的编写:

Windows 控制台输出如下的命令行来生成调用 WebService 的代码:

%AXIS2_HOME%/bin/wsdl2java –uri wsdl url –p  生成 java 类的包名   -s –o  客户端存根目录名

其中 -url 参数指定 wsdl 文件的路径,可以说本地路径,也可以是网络路径。 -p 参数指定了生成的 java 类的包名, -o 参数指定了生成的一系列文件保存的根目录。执行完命令后就会在当前目录下生成一个存根目录名的目录,里面就是 wsdl2java 生成的客户端代码。

7.AXIS2 复合类型数据的传递:

AXIS2 中可以直接使用将 WebService 方法的参数或返回值类型声明为数组或者类 ( 接口 )

注意:

(1). 在定义数组类型时只能使用一维数组,如果想传递多维数组,可以使用分隔符进行分割,如:

[java]   view plain copy
  1. String[] strArray =  new  String[]{“自行车, 飞机, 火箭”, “中国, 美国, 德国”, “超人, 蜘蛛侠, 钢铁侠”};  
 

可以将该数组看作是一个 3 × 3 的二维数组。

(2). 当传递自定义的类或接口时,请务必实现序列化。

8. 使用 services.xml 方式发布 WebService

(1). 编写服务端的类。

(2). 在工程 META-INF 目录下建 services.xml 文件,添加如下内容:

[xhtml]   view plain copy
  1. < serviceGroup >   
  2.        <!--第一种服务发布方式-->   
  3.        < service   name =”服务名” >   
  4.               < parameter   name =”ServiceClass” > 发布的服务类全路径 </ parameter >   
  5.               <!--处理WebService的处理器-->   
  6.               < messageReceivers >   
  7.                      <!--有返回值的处理器-->   
  8.                      < messageReceiver   mep =”http://www.w3.org/2004/08/wsdl/in-out”  
  9.                         class =”org.apache.axis2.rpc.receivers.RPCMessageReceiver” />   
  10.              <!--无返回值的处理器-->   
  11.              < messageReceiver   mep =”http://www.w3.org/2004/08/wsdl/in-only”  
  12.                         class =”org.apache.axis2.rpc.receivers.RPCInOnlyMessageReceiver” />   
  13.         </ messageReceivers >   
  14.     </ service >   
  15.     <!--第二种服务发布方式-->   
  16.     < service   name =”服务名” >   
  17.         < parameter   name =”ServiceClass” > 发布的服务类全路径 </ parameter >   
  18.         < operation   name =”服务的方法名” >   
  19.             < messageReceiver   class =”处理WebService方法的处理器(如,RPCMessageReceiver类)” />   
  20.         </ operation >   
  21.         ……  
  22.     </ service >   
  23.     ......  
  24. </ serviceGroup >   
 

注意:有返回值的处理器为: org.apache.axis2.rpc.receivers.RPCMessageReceiver

无返回值的处理器为: org.apache.axis2.rpc.receivers.RPCInOnlyMessageReceiver

(3). META-INF( 包含 services.xml) 和编译好的类使用 jar 工具命令打包成 ”.aar” 后缀名的文件。

(4). 将打包的 ”.aar” 文件发布到 axis2 的发布目录: %Tomcat%/webapps/axis2/WEB-INF/Services

注意:此种方法允许使用 package

9.AXIS2 使用 DataHandler 传输二进制文件:

(1). 服务端:

[java]   view plain copy
  1. private   void  writeInputStreamToFile(InputStream is, OutputStream os)  throw  Exception{  
  2.        int  n =  0 ;  
  3.        byte [] byffer =  new   byte [ 1024 ];  
  4.        while ((n = is.read(buffer)) >  0 ){  
  5.               os.write(buffer, 0 , n);  
  6. }  
  7. }  
  8.    
  9. public   boolean  uploadFileWithDataHandler(DataHandler handler, String fileName){  
  10.        FileOutputStream fos = null ;  
  11.        try {  
  12.               fos = new  FileOutputStream(fileName);  
  13.               writeInputStreamToFile(handler.getInputStream, fos);  
  14.               fos.close();  
  15. }catch (Exception e){  
  16.        return   false ;  
  17. }finally {  
  18.        if (fos !=  null ){  
  19.               try {  
  20.        fos.close();  
  21. }catch (IOException e){}  
  22. }  
  23. }  
  24.        return   true ;  
  25. }  
 

(2). 客户端:

[java]   view plain copy
  1. File file =  new  File(文件路径);  
  2. DataHandler dh = new  DataHandler( new  FileDataSource(file));  
  3. Object[] parameters = new  Object[]{dh, “文件名”};  
  4. QName qname = new  QName(“targetNamespace”, “服务端方法名(如:uploadFileWithDataHandler)”);  
  5. Class[] classes = new  Class[]{Boolean. class };  
  6. boolean  result = Service.invokeBlocking(qname, parameters, classes)[ 0 ];  
 

10.AXIS2 的状态管理:

(1).AXIS2 管理 WebService 的状态基本上对开发人员是透明的,在 WebService 类需要使用 org.apache,axis2.context.MessageContext org.apache.axis2.context.ServiceContext 类来保存与获取保存在服务端的状态信息,类似于使用 HTTPSession 接口的 getAttribute setAttribute 方法获得与设置 Session 属性。

(2). 此外,还需修改 services.xml 文件的内容,为 <service> 元素添加一个 scope 属性,该属性有 4 个可取的值: application soapsession transportsession request( 全部小写, request 是默认值 )

其中 transportsession application 分别实现同一个 WebService 类和跨 WebService 类的会话管理。

(3). 在客户端需要使用 setManageSession(true); 打开 session 管理功能。

11. 实现同一个 WebService Session 管理步骤:

(1). 使用 MessageContext ServiceContext 获取与设置 Session key-value 对。

(2). 为要进行 session 管理的 WebService 类在 services.xml 中所对应的 <service> 元素添加一个 scope 属性,并将该属性值设置为 ”transportsession”

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

12.WebService session 管理操作代码:

(1). 设置 key-value

[java]   view plain copy
  1. MessageContext mc = MessageContext.getCurrentMessageContext();  
  2. ServiceContext sc = mc.getServiceContext();  
  3. sc.setProperty(key, value);  
 

(2). 获取 value

[java]   view plain copy
  1. sc.getProperty(key);  
 

(3). 若用 stub 生成方式 ( 进入 axis2 安装目录使用 wsdl2java –uri wsdlURL –p  包名   –s –o  存放目录名 ) ,则需要添加 ”-serviceClient.getOptions().setManageSession(true);”

13.WebService 跨服务会话管理:

在多个 WebService 服务之间共享会话状态,也称为跨服务会话管理,实现跨服务会话管理与实现同一个服务的会话管理类似,步骤如下:

(1). 使用 MessageContext ServiceContext 获取与设置 Session key-value 对。

(2). 为要进行 session 管理的 WebService 类在 services.xml 中所对应的 <service> 元素添加一个 scope 属性,并将该属性值设置为 ”application”

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

注意: java 中只有将 scope 设置为 application 才支持跨服务的会话管理功能。

14.AXIS2 Spring 的集成:

(1). 为工程添加 Spring 支持,在 web.xml 文件中添加 spring 的相关配置。

(2). spring 配置文件中配置 AXIS2 ServiceBean 如下:

[xhtml]   view plain copy
  1. < bean   id "applicationContext"   
  2.     class  =  "org.apache.axis2.extensions.spring.receivers.ApplicationContextHolder" />   
  3. < bean   id "服务id"     class  =  "Web服务类的全路径"   > </ bean >   
 

(3). WEB-INF/services/ 下新建一个目录,这个名字可以起的随便,我们就起做 test 吧,然后在 WEB-INF/services/test/ 下建立 META-INF 这个目录,最后在 WEB-INF/services/test/META-INF/ 下建立 service.xml, 文件内容是:

[xhtml]   view plain copy
  1. < service   name "服务名"   >   
  2.        < description > 服务描述 </ description >   
  3.     <!--注意:不再是ServiceClass,而是有Spring提供-->   
  4.     < parameter   name "ServiceObjectSupplier"   >   
  5.         org.apache.axis2.extensions.spring.receivers.SpringAppContextAwareObjectSupplier  
  6.     </ parameter >   
  7.     < parameter   name "SpringBeanName"   > 在spring配置文件中配置的服务id </ parameter >   
  8.     < messageReceivers >   
  9.         < messageReceiver   mep "http://www.w3.org/2004/08/wsdl/in-only"   
  10.                         class  =  "org.apache.axis2.rpc.receivers.RPCInOnlyMessageReceiver"   />   
  11.               < messageReceiver   mep "http://www.w3.org/2004/08/wsdl/in-out"   
  12.                         class  =  "org.apache.axis2.rpc.receivers.RPCMessageReceiver" />   
  13.        </ messageReceivers >   
  14. </ service >   
 

15.AXIS2 的异步调用 WebService

同步调用时,如果被调用的 WebService 方法长时间没有返回,则客户端将一直处于阻塞状态,知道方法返回为止。为了避免长时间被阻塞,需要使用异步调用。 AXIS2 异步调用有两种方法:

(1). 多线程。

(2).RPCServiceClient 类提供了一个 invokeNoBlocking() 方法实现对 WebService 的异步调用。具体用法如下:

serviceClient.invokeNoBlocking(qname, parameters,  一个实现了 AXISCallback 接口的实例对象 );

实现 AXISCallback 接口需要实现其如下 4 个方法,实现异步回调:

onComplete() onError(Exception e) onFault(MessageContext mc) onMessage(MessageContext mc)

注意:当使用 wsdl2java 生成客户端调用 stub 时,会自动生成 服务名 +CallbackHandler” 的抽象回调类。

16.AXIS2 的模块:

AXIS2 可以通过模块 (Module) 进行扩展, AXIS2 模块至少需要有两个类,这两个类分别实现了 Module Handler 接口,开发和使用一个 AXIS2 的模板步骤如下:

(1). 编写实现了 Module 接口的类, AXIS2 模块在进行初始化、销毁等动作时会自动调用该类中的相应方法。

(2). 编写实现了 Handler 接口的类,该类是 AXIS2 模块的业务处理类。

(3). 编写 module.xml 文件,该文件放在工程的 META-INF 目录下,用于配置模块。

(4). axis2.xml 文件中配置 AXIS2 模块。

(5). services.xml 文件中配置 AXIS2 模块的引用, <module ref=” 模块名 ”/>

(6). 发布 AXIS2 模块,需要使用 jar 命令将 AXIS2 模块打包成 ”.mar” 后缀名包,然后将该后缀名为 ”.mar” 的文件拷贝到 AXIS2 模块发布目录 %Tomcat%/webapps/axis2/WEB-INF/modules

注意:模块和 Service 要分开打包,将 module 类, handler 类和 module.xml 打成 ”.mar” 文件,将 service 类和 services.xml 文件打成 ”.aar” 文件,分别发布。

猜你喜欢

转载自fackyou200.iteye.com/blog/1738482