前两天做一个Webservice接口工作,有位经理曾经对我说,如果你解决过一个问题,那么你以后必须成为这个领域的专家,不然等同于白做。所以在有时间的情况下,我简单做一下使用axis2作为客户端的情况下一些编码的实现内容。
首先应该部署一套服务以应对客户端调用。我要做的例子不是很麻烦,所以只需要三个接口就可以了,一个接收字符串参数,返回字符串参数。另外两个做上传和下载。一共三个接口,我已经在附件上传了一个类,这个类编译后的class文件放到下载的axis2事例工程的WEB-INF下的pojo文件夹中,pojo文件夹是自己创建的。这样就会发布一个有三个方法的接口。具体关于axis2的发布网络上内容很多,我也会在以后博客中做详细解释。为了方便我也在这里放出代码。 Java代码
import java.io.FileOutputStream; 
SimpleDateFormat; 
import java.util.Date; 
/** 
* 这个是作为服务端的方法类,不能带有命名空间,方法必须为public 
* 崔素强 
* cuisuqiang@163.COM 
*/ 
public class MyAxis2Service {     
/* 
* 请求的方法,输出接收到的参数,返回时间戳字符串 
*/ 
public String getServiceInit(String name){ 
System.out.println("you name is :" + name); 
SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); 
return format.format(new Date()); 
/
/ 下载图像 
public byte[] dowImageWithByte() { 
byte[] imageByte = null; 
try { 
// 下面的代码调用uploadImageWithByte方法上传图像文件 
// 打开图像文件,确定图像文件的大小 
java.io.File file = new java.io.File("c:\\test.jpg"); 
java.io.FileInputStream fis = new java.io.FileInputStream("c:\\test.jpg"); 
// 创建保存要上传的图像文件内容的字节数组 
imageByte = new byte[(int) file.length()]; 
} catch (Exception e) { 
return null; 
} finally { 
return imageByte; 
// 上传图像,imageByte参数表示上传图像文件的字节 
public boolean uploadImageWithByte(byte[] imageByte, int length) { 
FileOutputStream fos = null; 
try { 
// 将上传的图像保存在D盘的test1.jpg文件中 
fos = new FileOutputStream("d:\\test1.jpg"); 
// 开始写入图像文件的字节 
fos.write(imageByte, 0, length); 
fos.close(); 
} catch (Exception e) { 
return false; 
} finally { 
if (fos != null) { 
try { 
fos.close();
} catch (Exception e) { 
return true; 
import java.io.FileOutputStream;
SimpleDateFormat;
import java.util.Date;
/**
* 这个是作为服务端的方法类,不能带有命名空间,方法必须为public
* 崔素强
* cuisuqiang@163.COM
*/
public class MyAxis2Service {
/*
* 请求的方法,输出接收到的参数,返回时间戳字符串
*/
public String getServiceInit(String name){
System.out.println("you name is :" + name);
SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
return format.format(new Date());
}
// 下载图像
public byte[] dowImageWithByte() {
byte[] imageByte = null;
try {
// 下面的代码调用uploadImageWithByte方法上传图像文件
// 打开图像文件,确定图像文件的大小
java.io.File file = new java.io.File("c:\\test.jpg");
java.io.FileInputStream fis = new java.io.FileInputStream("c:\\test.jpg");
// 创建保存要上传的图像文件内容的字节数组
imageByte = new byte[(int) file.length()];
} catch (Exception e) {
return null;
} finally {
}
return imageByte;
}
// 上传图像,imageByte参数表示上传图像文件的字节
public boolean uploadImageWithByte(byte[] imageByte, int length) {
FileOutputStream fos = null;
try {
/
/ 将上传的图像保存在D盘的test1.jpg文件中
fos = new FileOutputStream("d:\\test1.jpg");
// 开始写入图像文件的字节
fos.write(imageByte, 0, length);
fos.close();
} catch (Exception e) {
return false;
} finally {
if (fos != null) {
try {
fos.close();
} catch (Exception e) {
}
}
}
return true;
}
}
其中要上传和下载的文件是图片,请自己事先准备好。
下面创建一个项目,将所需的JAR包加到工程中,发现有的人说如果不知道是那个包就全加进去,可是axis2的包有几十个,我也尝尽了JAR冲突的痛苦,所以我在这里告诉大家,只需要加我附件里面的几个JAR就可以了。
首先编码调用简单接口的代码,传递的参数和返回的参数都是字符串。发现网络上的例子都是RPC的,
为了方便学习,我会给出两种调用方式。首先的网络上通用的方式: Java代码
l.namespace.QName; 
import org.apache.axis2.addressing.EndpointReference; 
import org.apache.axis2.client.Options; 
import org.apache.axis2.rpc.client.RPCServiceClient; 
/** 
* RPC axis2调用方式 
* @author cuisuqiang 
*/ 
public class RpcCommonClient { 
@SuppressWarnings("unchecked") 
public static void main(String[] args) { 
try { 
// 获得客户端 
RPCServiceClient serviceClient = new RPCServiceClient(); 
// 可以
在该对象中设置服务端的验证信息 
Options options = Options(); 
EndpointReference targetEPR = new EndpointReference("127.0.0.1:8080/axis2/services/MyAxis2Service"); 
options.setTo(targetEPR); 
// 在创建QName对象时,QName类的构造方法的第一个参数表示WSDL文件的命名空间名,也就是<wsdl:definitions>元素的targetNamespace属性值 
QName opAddEntry = new QName("/axis2","getServiceInit"); 
// 参数,如果有多个,继续往后面增加即可,不用指定参数的名称 
Object[] opAddEntryArgs = new Object[] {"cuisuqiang" }; 
// 返回参数类型,这个和axis1有点区别 
// invokeBlocking方法有三个参数,其中第一个参数的类型是QName对象,表示要调用的方法名; 
// 第二个参数表示要调用的WebService方法的参数值,参数类型为Object[]; 
// 第三个参数表示WebService方法的返回值类型的Class对象,参数类型为Class[]。 
// 当方法没有参数时,invokeBlocking方法的第二个参数值不能是null,而要使用new Object[]{} 
// 如果被调用的WebService方法没有返回值,应使用RPCServiceClient类的invokeRobust方法, 
// 该方法只有两个参数,它们的含义与invokeBlocking方法的前两个参数的含义相同 
Class[] classes = new Class[] { String.class }; 
System.out.println(serviceClient.invokeBlocking(opAddEntry,opAddEntryArgs, classes)[0]);   
} catch (Exception e) { 
e.printStackTrace(); 
l.namespace.QName;
import org.apache.axis2.addressing.EndpointReference;
import org.apache.axis2.client.Options;
import org.apache.axis2.rpc.client.RPCServiceClient;
/**
* RPC axis2调用方式
* @author cuisuqiang
*/
public class RpcCommonClient {
@SuppressWarnings("unchecked")
public static void main(String[] args) {
try {
// 获得客户端
RPCServiceClient serviceClient = new RPCServiceClient();
// 可以在该对象中设置服务端的验证信息
Options options = Options();
EndpointReference targetEPR = new EndpointReference("127.0.0.1:8080/axis2/services/MyAxis2Service");
options.setTo(targetEPR);
// 在创建QName对象时,QName类的构造方法的第一个参数表示WSDL文件的命名空间名,也就是<wsdl:definitions>元素的targetNamespace属性值
QName opAddEntry = new QName("/axis2","getServiceInit");
// 参数,如果有多个,继续往后面增加即可,不用指定参数的名称
Object[] opAddEntryArgs = new Object[] {"cuisuqiang" };
// 返回参数类型,这个和axis1有点区别
// invokeBlocking方法有三个
参数,其中第一个参数的类型是QName对象,表示要调用的方法名;
// 第二个参数表示要调用的WebService方法的参数值,参数类型为Object[];
// 第三个参数表示WebService方法的返回值类型的Class对象,参数类型为Class[]。
// 当方法没有参数时,invokeBlocking方法的第二个参数值不能是null,而要使用new Object[]{}
// 如果被调用的WebService方法没有返回值,应使用RPCServiceClient类的invokeRobust方法,
// 该方法只有两个参数,它们的含义与invokeBlocking方法的前两个参数的含义相同
Class[] classes = new Class[] { String.class };
System.out.println(serviceClient.invokeBlocking(opAddEntry,opAddEntryArgs, classes)[0]);
} catch (Exception e) {
e.printStackTrace();
}
}
} RPC的调用方式还是非常简洁明了的,但是axis2的调用方式是有很多种实现的。下面的实现方式,使用到了一些底层的东西,不过更加让我们开发人员明了: Java代码
import java.util.Iterator; 
import org.OMAbstractFactory; 
import org.OMElement; 
import org.OMFactory; 
import org.OMNamespace; 
import org.apache.axis2.addressing.EndpointReference; 
import org.apache.axis2.client.Options; 
import org.apache.axis2.client.ServiceClient; 
/** 
* Axis2客户端 
* 崔素强 cuisuqiang@163 
*/ 
public final class AxisWebServiceClient { 
public static void main(String[] args) { 
// 直接运行也可以看到效果 
callWebservice2(); 
/** 
* 客户端调用service 
*/ 
@SuppressWarnings("unchecked") 
public static void callWebservice2() { 
try { 
// 服务地址,服务地址,命名空间,方法名称,组装参数,返回数据解析,可以自己根据实际情况编码 
EndpointReference targetEPR = new EndpointReference("127.0.0.1:8080/axis2/services/MyAxis2Service");    webservice实现
ServiceClient serviceClient = new ServiceClient(); 
Options options = new Options(); 
options.setTo(targetEPR); 
serviceClient.setOptions(options); 
OMFactory fac = OMFactory();                 
// 命名空间,有时命名空间不增加没事,不过最好加上,因为有时有事,你懂的 
OMNamespace omNs = ateOMNamespace("/axis2", "");           
//为SOAP Header构造验证信息,如果你的服务端是没有验证的,那么你不用在Header中增加验证信息 
//          OMElement header = ateOMElement("AuthenticationToken", omNs);             
//          OMElement ome_user = ateOMElement("Username", omNs); 
//          ome_user.setText(""); 
//   
header.addChild(ome_user); 
//          OMElement ome_pass = ateOMElement("Password", omNs); 
//          ome_pass.setText(""); 
//          header.addChild(ome_pass); 
//          serviceClient.addHeader(header); 
//调用据方法 
OMElement data = ateOMElement("getServiceInit", omNs);             
/
/ 设置参数,如果参数名称没有设置正确,后果自负 
OMElement metaData = ateOMElement("name", omNs); 
metaData.setText("cuisuqiang"); 
data.addChild(metaData);             
//发送请求 
import java.util.Iterator;
import org.OMAbstractFactory;
import org.OMElement;
import org.OMFactory;
import org.OMNamespace;
import org.apache.axis2.addressing.EndpointReference;
import org.apache.axis2.client.Options;
import org.apache.axis2.client.ServiceClient;
/**
* Axis2客户端
* 崔素强 cuisuqiang@163
*/
public final class AxisWebServiceClient {
public static void main(String[] args) {
// 直接运行也可以看到效果
callWebservice2();
}
/
**
* 客户端调用service
*/
@SuppressWarnings("unchecked")
public static void callWebservice2() {
try {
// 服务地址,服务地址,命名空间,方法名称,组装参数,返回数据解析,可以自己根据实际情况编码
EndpointReference targetEPR = new EndpointReference("127.0.0.1:8080/axis2/services/MyAxis2Service");
ServiceClient serviceClient = new ServiceClient();
Options options = new Options();
options.setTo(targetEPR);
serviceClient.setOptions(options);
OMFactory fac = OMFactory();   
// 命名空间,有时命名空间不增加没事,不过最好加上,因为有时有事,你懂的
OMNamespace omNs = ateOMNamespace("/axis2", ""); 
//为SOAP Header构造验证信息,如果你的服务端是没有验证的,那么你不用在Header中增加验证信息
//  OMElement header = ateOMElement("AuthenticationToken", omNs); 
//  OMElement ome_user = ateOMElement("Username", omNs);
//  ome_user.setText("");
//      header.addChild(ome_user);
//      OMElement ome_pass = ateOMElement("Password", omNs);
//      ome_pass.setText("");
/
/      header.addChild(ome_pass);
//  serviceClient.addHeader(header);
//调用据方法
OMElement data = ateOMElement("getServiceInit", omNs);     
// 设置参数,如果参数名称没有设置正确,后果自负
OMElement metaData = ateOMElement("name", omNs);
metaData.setText("cuisuqiang");
data.addChild(metaData);     
//发送请求
以上方法调用后返回的是OMElement对象,而传递参数也用到了该对象,具体关于该对象的一些内容,可以查看源码