Chinaunix首页 | 论坛 | 博客
  • 博客访问: 6662379
  • 博文数量: 915
  • 博客积分: 17977
  • 博客等级: 上将
  • 技术积分: 8846
  • 用 户 组: 普通用户
  • 注册时间: 2005-08-26 09:59
个人简介

一个好老好老的老程序员了。

文章分类

全部博文(915)

文章存档

2022年(9)

2021年(13)

2020年(10)

2019年(40)

2018年(88)

2017年(130)

2015年(5)

2014年(12)

2013年(41)

2012年(36)

2011年(272)

2010年(1)

2009年(53)

2008年(65)

2007年(47)

2006年(81)

2005年(12)

分类: 系统运维

2011-05-12 23:33:27

Apache Axis2 是Axis的后续版本,是新一代的SOAP引擎。

Axis2 是对 Axis 进行了彻底的重写的一个新项目了,它使用了新的模块化架构,更方便于功能性的扩展等等


Axis2是一套崭新的WebService引擎,该版本是对Axis1.x重新设计的产物。Axis2不仅支持SOAP1.1和SOAP1.2,还集成了非常流行的REST WebService,同时还支持Spring、JSON等技术



wsdl2java -uri http: -p client -s -o stub


安装AXIS2很简单,只需要将axis2-1.4.1-war.zip包中的axis2.war放到tomcat的webapps下面,启动tomcat,在地址栏中输入:,如果出现axis2的欢迎页面,就表示安装成功了。



在Axis2中,不需要进行任何的配置,就可以直接将一个简单的POJO发布成WebService,其中POJO中所有的public方法将被发布成Webservice方法,例如:
import java.util.Random;


public class SimpleService {

public String getGreeting(String name){
return "你好:"+name;
}

public int getPrice(){
return new Random().nextInt(1000);
}

}

编译后,将该类的.class文件放到webapps/axis2/WEB-INF/pojo目录(如果没有,则新建该目录)下即可,任何在地址栏中输入:/services/listServices,就可以列出发布的所有类。

在地址栏中分别输入下面的内容,就可以调用相应的WebService,并在页面中显示调用结果:
/services/SimpleService/getGreeting?name=cxm
/services/SimpleService/getPrice

在发布pojo类时要注意:
1.POJO类不能使用package关键字声明包;
2.Axis2在默认情况下可以热发布WebService,即只要把.class文件复制到pojo目录下,不需要重新启动tomcat就可以自动发布WebService。如果想取消Axis2的热发布功能,可以修改axis2/WEB-INF/conf/axis2.xml配置文件,true把true改为false即可。
3.axis2虽然支持热发布,但不支持热更新,就是说如果你修改了WebService,那必须重启tomcat才能生效,也可以修改配置文件,让axis2支持热更新,在同样的配置文件里修改false即可
4.pojo目录是默认的发布目录,如果想改成其它目录还是修改配置文件axis2.xml,



WebService是为程序服务的,只在浏览器中访问WebService是没有任何意义的。发布WebService主要是为了在客户端程序中调用,客户端调用WebService的代码如下:

package com.cxm;



import javax.xml.namespace.QName;

import org.apache.axis2.addressing.EndpointReference;
import org.apache.axis2.client.Options;
import org.apache.axis2.rpc.client.RPCServiceClient;

public class TestWS {


public static void main(String[] args)throws Exception {

                // 使用RPC方式调用WebService
RPCServiceClient serviceClient=new RPCServiceClient();

Options op=serviceClient.getOptions();

                // 指定调用WebService的url,到对应的类即可
EndpointReference tergetEPR=new EndpointReference(
"/services/SimpleService");

op.setTo(tergetEPR);
// 指定方法接受的参数
Object[] opadd=new Object[]{"小敏"};

                // 指定返回值的类型
Class[] classes = new Class[]{String.class};
                // 指定WSDL文件的命名空间已经要调用的方法名称
QName qn= new QName("","getGreeting");

                // 调用WebService并输出返回值
System.out.println(serviceClient.invokeBlocking(qn,opadd,classes)[0]);   
}

}

编写客户端代码时要注意:
1.客户端代码需要axis2的jar包,如果不确定需要哪些包,则应该保护所有axis2所有的jar包;
2.invokeBlocking方法的第一个参数为QName对象,表示要调用的方法名,第一个参数表示要传递给方法的参数,参数类型为Object[],如果方法没有参数列表,不能使用null,而应该使用new Object[]{};第三个参数是方法的返回类型,参数类型为Class[]。
3.如果WebService方法没有返回值,则应该调用invokeRobust方法,该方法只有两个参数,且与invokeBlocking的前两个参数的意义相同;
4.QName对象的第一个参数表示wsdl文件的命名空间名,即元素targetNamespaces属性的值.








在实际的应用中,不仅需要使用WebService来传递简单类型的数据,有时也需要传递更复杂的数据。
在Axis2中可以直接使用webService方法的参数或返回值来传递复合数据类型。但要注意,在定义数据类型时只能使用一维数组,如果要传递多维数组可以使用分隔符进行分割,例如:

String[] array  = new String[]("自行车,飞机,火箭","超人,蜘蛛侠,钢铁侠");


如果WebService类中有个方法如下:
public String[] getArray(){
String[] strArray=new String[]{"自行车","飞机","火箭"};
return strArray;
}

那么客户端程序就应该这样写:
qn= new QName("","getArray");
String[] stra=(String[])serviceClient.invokeBlocking(qn,new Object[]{},new Class[]{String[].class})[0];

for(String s:stra){
    System.out.println(s);
}






如果定义了一个类,如下:
package data;

public class DataForm implements java.io.Serializable{

private String name="cxm";
private int age=27;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}

}

在WebService中有如下方法,要返回DataForm对象:
public DataForm getDataForm(){
return new DataForm();
}

那么在客户端就应该这样调用:
qn= new QName("","getDataForm");
DataForm stras=(DataForm)serviceClient.invokeBlocking(qn,new Object[]{},new Class[]{DataForm.class})[0];

System.out.println(stras.getAge());
System.out.println(stras.getName());

注意:
1.一定要把DataFrom类所在的包引进来;
2.DataFrom由于该类定义在包data中,所以应该把该类放在WEB-INF/classes/data目录下;
3.通过序列化的方式传递对象实例只适用于客户端与服务器为同一种语言或技术的情况,因为.net和java序列化和反序列化存在着差异;
阅读(997) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~