`
cuisuqiang
  • 浏览: 3960236 次
  • 性别: Icon_minigender_1
  • 来自: 北京
博客专栏
3feb66c0-2fb6-35ff-968a-5f5ec10ada43
Java研发技术指南
浏览量:3670073
社区版块
存档分类
最新评论

axis2客户端编码,RPC,OMElement,上传下载实现,服务端验证

    博客分类:
  • J2EE
阅读更多
  1. 前两天做一个Webservice接口工作,有位经理曾经对我说,如果你解决过一个问题,那么你以后必须成为这个领域的专家,不然等同于白做。所以在有时间的情况下,我简单做一下使用axis2作为客户端的情况下一些编码的实现内容。
  2. 首先应该部署一套服务以应对客户端调用。我要做的例子不是很麻烦,所以只需要三个接口就可以了,一个接收字符串参数,返回字符串参数。另外两个做上传和下载。一共三个接口,我已经在附件上传了一个类,这个类编译后的class文件放到下载的axis2事例工程的WEB-INF下的pojo文件夹中,pojo文件夹是自己创建的。这样就会发布一个有三个方法的接口。具体关于axis2的发布网络上内容很多,我也会在以后博客中做详细解释。为了方便我也在这里放出代码。
    import java.io.FileOutputStream;
    import java.text.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()];
    			 fis.read(imageByte);
    		} 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;
    	}
    }
    
     其中要上传和下载的文件是图片,请自己事先准备好。
  3. 下面创建一个项目,将所需的JAR包加到工程中,发现有的人说如果不知道是那个包就全加进去,可是axis2的包有几十个,我也尝尽了JAR冲突的痛苦,所以我在这里告诉大家,只需要加我附件里面的几个JAR就可以了。
  4. 首先编码调用简单接口的代码,传递的参数和返回的参数都是字符串。发现网络上的例子都是RPC的,为了方便学习,我会给出两种调用方式。首先的网络上通用的方式:
    import javax.xml.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 = serviceClient.getOptions();
    			EndpointReference targetEPR = new EndpointReference("http://127.0.0.1:8080/axis2/services/MyAxis2Service");
    			options.setTo(targetEPR);
    			// 在创建QName对象时,QName类的构造方法的第一个参数表示WSDL文件的命名空间名,也就是<wsdl:definitions>元素的targetNamespace属性值
    			QName opAddEntry = new QName("http://ws.apache.org/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的调用方式是有很多种实现的。下面的实现方式,使用到了一些底层的东西,不过更加让我们开发人员明了:
    import java.util.Iterator;
    import org.apache.axiom.om.OMAbstractFactory;
    import org.apache.axiom.om.OMElement;
    import org.apache.axiom.om.OMFactory;
    import org.apache.axiom.om.OMNamespace;
    import org.apache.axis2.addressing.EndpointReference;
    import org.apache.axis2.client.Options;
    import org.apache.axis2.client.ServiceClient;
    
    /**
     * Axis2客户端
     * 崔素强 cuisuqiang@163.com
     */
    public final class AxisWebServiceClient {
    	
    	public static void main(String[] args) {
    		// 直接运行也可以看到效果
    		callWebservice2();
    	}
    	
    	/**
    	 * 客户端调用service
    	 */
    	@SuppressWarnings("unchecked")
    	public static void callWebservice2() {
    		try {
    			// 服务地址,服务地址,命名空间,方法名称,组装参数,返回数据解析,可以自己根据实际情况编码
    			EndpointReference targetEPR = new EndpointReference("http://127.0.0.1:8080/axis2/services/MyAxis2Service"); 
    			ServiceClient serviceClient = new ServiceClient();
    			Options options = new Options();
    			options.setTo(targetEPR);
    			serviceClient.setOptions(options);
    			OMFactory fac = OMAbstractFactory.getOMFactory();				
    			// 命名空间,有时命名空间不增加没事,不过最好加上,因为有时有事,你懂的
    			OMNamespace omNs = fac.createOMNamespace("http://ws.apache.org/axis2", "");			
    			//为SOAP Header构造验证信息,如果你的服务端是没有验证的,那么你不用在Header中增加验证信息
    //			OMElement header = fac.createOMElement("AuthenticationToken", omNs);			
    //			OMElement ome_user = fac.createOMElement("Username", omNs);
    //			ome_user.setText("");
    //		    header.addChild(ome_user);
    //		    OMElement ome_pass = fac.createOMElement("Password", omNs);
    //		    ome_pass.setText("");
    //		    header.addChild(ome_pass);
    //			serviceClient.addHeader(header);
    			//调用据方法
    		    OMElement data = fac.createOMElement("getServiceInit", omNs);		    
    		    // 设置参数,如果参数名称没有设置正确,后果自负
    		    OMElement metaData = fac.createOMElement("name", omNs);
    		    metaData.setText("cuisuqiang");
    		    data.addChild(metaData);		    
    		    //发送请求
    
     以上方法调用后返回的是OMElement对象,而传递参数也用到了该对象,具体关于该对象的一些内容,可以查看源码了解。
  5. 下面我们来看一下,如何上传一个文件,大家也看到了服务端的地方我文件用的是字节数组,为的是不同业务调用方便和统一。同样,先来看一下RPC调用的方式,这里给出一个方法,大家看代码即可:
    	/**
    	 * 上传
    	 */
    	@SuppressWarnings("unchecked")
    	public static void test2() {
    		try {
    			RPCServiceClient serviceClient = new RPCServiceClient();
    			Options options = serviceClient.getOptions();
    			EndpointReference targetEPR = new EndpointReference("http://localhost:8080/axis2/services/MyAxis2Service");
    			options.setTo(targetEPR);
    			QName opAddEntry;
    			byte[] buffer;
    			// 下面的代码调用uploadImageWithByte方法上传图像文件
    			// 打开图像文件,确定图像文件的大小
    			java.io.File file = new java.io.File("c:\\test.jpg");
    			java.io.FileInputStream fis = new java.io.FileInputStream("c:\\test.jpg");
    			// 创建保存要上传的图像文件内容的字节数组
    			buffer = new byte[(int) file.length()];
    			// 将图像文件的内容读取buffer数组中
    			int n = fis.read(buffer);
    			Object[] opAddEntryArgs = new Object[] { buffer, n };
    			Class[] classes = new Class[] { Boolean.class };
    			opAddEntry = new QName("http://ws.apache.org/axis2","uploadImageWithByte");
    			fis.close();
    			// 开始上传图像文件,并输出uploadImageWithByte方法的返回传
    			System.out.println(serviceClient.invokeBlocking(opAddEntry,opAddEntryArgs, classes)[0]);
    		} catch (Exception e) {
    			e.printStackTrace();
    		}
    	}
     从这里我更感觉到了这种调用方式的简洁性,因为参数的传递非常容易,放到参数的数组中就行了。对比一下,再看一下另一种实现方式:
    	/**
    	 * 上传附件
    	 */
    	@SuppressWarnings("unchecked")
    	public static void test1() {
    		try {
    			// 服务地址,服务地址,命名空间,方法名称,组装参数,返回数据解析,可以自己根据实际情况编码
    			EndpointReference targetEPR = new EndpointReference("http://127.0.0.1:8080/axis2/services/MyAxis2Service");
    			ServiceClient serviceClient = new ServiceClient();
    			Options options = new Options();
    			options.setTo(targetEPR);
    			serviceClient.setOptions(options);
    			OMFactory fac = OMAbstractFactory.getOMFactory();
    			OMNamespace omNs = fac.createOMNamespace("http://ws.apache.org/axis2", "");
    			// 调用据方法
    			OMElement data = fac.createOMElement("uploadImageWithByte", omNs);
    			// 增加附件
    			OMElement fileData = fac.createOMElement("imageByte", omNs);
    			java.io.File file = new java.io.File("c:\\test.jpg");
    			FileDataSource fs = new FileDataSource(file);
    			DataHandler fileHandle = new DataHandler(fs);
    			OMText textData = fac.createOMText(fileHandle, true);
    			fileData.addChild(textData);
    			data.addChild(fileData);
    			// 增加元数据
    			OMElement metaData = fac.createOMElement("length", omNs);
    			metaData.setText(file.length() + "");
    			data.addChild(metaData);
    			// 发送请求
    			OMElement results = serviceClient.sendReceive(data);
    			Iterator it = results.getChildElements();
    			while (it.hasNext()) {
    				OMElement el = (OMElement) it.next();
    				System.out.println("element.getLocalName(): "+ el.getLocalName());
    				System.out.println("element.getText(): " + el.getText());
    			}
    		} catch (Exception e) {
    			e.printStackTrace();
    		}
    	}
     虽然看着是没有第一种好看,不过我也很喜欢,为什么?多写点代码有时候才能显出来我们编码人员的重要性啊,呵呵呵,开玩笑了。
  6. 一下再看看下载的方法,首先还是使用第一种方式:
    	/**
    	 * 下载
    	 */
    	public static void test1() {
    		try {
    			RPCServiceClient serviceClient = new RPCServiceClient();
    			Options options = serviceClient.getOptions();
    			EndpointReference targetEPR = new EndpointReference("http://localhost:8080/axis2/services/MyAxis2Service");
    			options.setTo(targetEPR);
    			QName opAddEntry;
    			byte[] buffer;
    			opAddEntry = new QName("http://ws.apache.org/axis2","dowImageWithByte");
    			buffer = (byte[]) serviceClient.invokeBlocking(opAddEntry,new Object[] {}, new Class[] { byte[].class })[0];
    			FileOutputStream fos = null;
    			try {
    				fos = new FileOutputStream("d:\\test1.jpg");
    				// 开始写入图像文件的字节
    				fos.write(buffer, 0, buffer.length);
    				fos.close();
    			} catch (Exception e) {
    				e.printStackTrace();
    			} finally {
    				if (fos != null) {
    					try {
    						fos.close();
    					} catch (Exception e) {
    						e.printStackTrace();
    					}
    				}
    			}
    		} catch (Exception e) {
    			e.printStackTrace();
    		}
    	}
     同样很简单呀,只要强制转换就可以了。下面继续看一下第二种方式的代码:
    	/**
    	 * 下载
    	 */
    	@SuppressWarnings("unchecked")
    	public static void test2() {
    		try {
    			// 服务地址,服务地址,命名空间,方法名称,组装参数,返回数据解析,可以自己根据实际情况编码
    			EndpointReference targetEPR = new EndpointReference("http://127.0.0.1:8080/axis2/services/MyAxis2Service");
    			ServiceClient serviceClient = new ServiceClient();
    			Options options = new Options();
    			options.setTo(targetEPR);
    			serviceClient.setOptions(options);
    			OMFactory fac = OMAbstractFactory.getOMFactory();
    			OMNamespace omNs = fac.createOMNamespace("http://ws.apache.org/axis2", "");
    			// 调用据方法
    			OMElement data = fac.createOMElement("dowImageWithByte", omNs);
    			// 发送请求
    			OMElement results = serviceClient.sendReceive(data);
    			Iterator it = results.getChildElements();
    			while (it.hasNext()) {
    				OMElement el = (OMElement) it.next();
    				OMText binaryNode = (OMText) el.getFirstOMChild();
    				binaryNode.setOptimize(true); //必须加此句,否则会出现ContentID is null的异常!
    				DataHandler dh = (DataHandler) binaryNode.getDataHandler();
    				FileOutputStream fileOutStream = new FileOutputStream("d:\\test.jpg");
    				InputStream is = dh.getInputStream();
    				fileOutStream.write(IOUtils.getStreamAsByteArray(is));
    			}
    		} catch (Exception e) {
    			e.printStackTrace();
    		}
    	}
     在接收到参数后的解析工作确实有点麻烦。不过,你知道就行了,底层的东西依赖少,出问题也好解决。
  7. 不过是不是看着有点晕呀,没关系,每次都会上传工程给大家的。在附件中大家解压后可以直接导入到MyEclipse中查看代码。可以直接main方法运行,也可以跑起来点击首页的按钮来触发后台调用。其中MyAxis2Service.java是要部署的服务端代码,不用关心。

请您到ITEYE看我的原创:http://cuisuqiang.iteye.com

或支持我的个人博客,地址:http://www.javacui.com

 

7
0
分享到:
评论
15 楼 coconut_zhang 2013-07-02  
没时间细细研究,看帖子和评论,胜读十年书。
14 楼 xaocaotanghui 2013-01-16  
博主的这篇帖子让我想起了之前遇到的一个问题,cxf开发的服务端,客户端是用axis2,调用的时候用的是RPC,调试的时候,服务端接受的参数始终为null,折腾了两三天,当时没找到第二种方法,现在想想,如果用第二种方式访问,问题应该就解决了,好帖子,收下了
13 楼 cindy_zhong 2012-12-11  
不知道博主有不有在WAS上验证,在WAS7上以WAR包的方式发布后死活找不到访问的资源,不解!
12 楼 cuisuqiang 2012-08-18  
xwqiang 写道
最近在看webservice ,涉及的技术框架有axis2、cxf,我都不明白哪个是用axis2实现的 哪个是cxf实现的?求回复。。。。

先回复给你:
首先不管是你给别人提供还是别人给你提供,你是不用关系实现的
再者,看提供的连接路径好像是能看出来的,这个我回头实际看一下再具体回复
11 楼 xwqiang 2012-08-17  
最近在看webservice ,涉及的技术框架有axis2、cxf,我都不明白哪个是用axis2实现的 哪个是cxf实现的?求回复。。。。
10 楼 cn-done 2012-01-09  
IO居然都不关闭的。。。
9 楼 cuisuqiang 2011-12-29  
kimmking 写道
http://axis.apache.org/axis2/java/core/docs/mtom-guide.html

两种方式
1、axis自定义的二进制数据传输机制MTOM
2、基于http的multipart的 WS-attachment

非常谢谢你给的资源,当初我感觉那样写不是很通用,所以才使用了字节数组,可能是考虑的太多了,之后我会根据你给的资源继续更新的。
8 楼 kimmking 2011-12-29  
http://axis.apache.org/axis2/java/core/docs/mtom-guide.html

两种方式
1、axis自定义的二进制数据传输机制MTOM
2、基于http的multipart的 WS-attachment
7 楼 cuisuqiang 2011-12-29  
关于Axis2的发布,也写了一点东西,希望对刚学习的人有所帮助!详细请查看:http://cuisuqiang.iteye.com/blog/1328683
6 楼 cuisuqiang 2011-12-28  
hy_agui 写道
   

谢谢了,好好学习啊
5 楼 cuisuqiang 2011-12-28  
a49688448 写道
写不错 很详细 学习了

如果是入门的话,那越详细越好。我深有体会了。
4 楼 a49688448 2011-12-28  
写不错 很详细 学习了
3 楼 hy_agui 2011-12-28  
   
2 楼 cuisuqiang 2011-12-28  
kimmking 写道
1、这两种写法是一样的,rpc方式和axiom拼dom的方式。
只是后一种的粒度更小,可以自己丢进入一些自定义的东西。

2、不建议用这种方式传文件,soap报文中byte[]都被序列化到方法里,效率太低。
看看WS-attachment




关于在webservice中使用什么样的方式来传递附件,我还真不知道那个效率高些,我觉得使用字节数组更通用一些。
1 楼 kimmking 2011-12-28  
1、这两种写法是一样的,rpc方式和axiom拼dom的方式。
只是后一种的粒度更小,可以自己丢进入一些自定义的东西。

2、不建议用这种方式传文件,soap报文中byte[]都被序列化到方法里,效率太低。
看看WS-attachment



相关推荐

    axis2客户端调用axis1服务接口

    axis2客户端调用axis1服务接口 调用方式 使用RPC方式调用WebService,为了防止冲突可以增加 // 与weblogic的lib冲突配置 System.setProperty("javax.xml.stream.XMLInputFactory", ...

    axis2客户端调用服务端,带用户身份认证

    当涉及到“axis2客户端调用服务端,带用户身份认证”时,我们主要关注的是如何在 Axis2 客户端中添加安全机制,确保只有经过验证的用户能够访问服务。 首先,理解身份认证是网络安全的基础。在Web服务中,通常采用...

    axis2生成客户端服务端代码

    ### Axis2生成客户端与服务端代码详解 #### 一、Axis2简介 Axis2是Apache组织下的一个开源项目,它是一种高性能、轻量级的Web服务框架,支持SOAP和REST等协议,能够帮助开发者轻松地构建和部署Web服务。Axis2提供了...

    axis2客户端所需要的所有jar包

    本文将详细阐述Axis2客户端所需的所有jar包及其在调用服务端、测试接口过程中的作用。 首先,让我们了解什么是Axis2。Axis2是Apache软件基金会的一个开源项目,它提供了一个灵活、高性能的SOAP引擎,支持多种协议,...

    基于axis2实现的webservice简单实现(客户端+服务端)。

    【标题】中的“基于axis2实现的webservice简单实现(客户端+服务端)”表明了本文将探讨如何使用Apache Axis2框架来创建和消费Web服务。Apache Axis2是Apache软件基金会开发的一个Web服务引擎,它提供了高效且灵活的...

    axis2客户端以及服务端所有jar包

    这个压缩包包含Axis2客户端和服务端所需的全部jar包,使得开发者能够在Java环境中轻松地创建、部署和使用Web服务。 1. **Axis2简介** Axis2是第二代的Apache SOAP引擎,它在Axis1的基础上进行了很多改进,提供了更...

    axis2客户端需要的jar包

    在开发Axis2客户端时,正确地引入所需的jar包是至关重要的,因为这些库提供了与服务交互所需的各种功能。以下是关于Axis2客户端需要的jar包及其功能的详细解释: 1. **axis2-adb.jar**:这个jar包包含了Axis2的数据...

    AXIS2中OMElement和Java对象之间的转换

    AXIS2 中 OMElement 和 Java 对象之间的转换 AXIS2 是一个流行的开源 Web 服务框架,它提供了一个强大的对象模型,称为 AXIOM(AXIs 对象模型),用于提高 XML 处理期间的内存使用率和性能。AXIOM 通过使用 ...

    axis生成webservice服务端和客户端详细说明及实例

    Axis为开发者提供了便捷的工具来创建和使用Web服务,无论是服务端的搭建还是客户端的调用,都能通过简单的命令和代码实现。通过理解WSDL文件,你可以更好地理解Web服务的结构和交互方式。在实际项目中,灵活运用Axis...

    Axis 服务端/客户端 样例

    【Axis 服务端/客户端 样例】是一个用于学习和实践Axis框架的示例资源包。Axis是一个开源的Web服务工具包,它主要用于构建和部署基于SOAP(简单对象访问协议)的Web服务。这个资源包涵盖了 Axis 1.4 的完整二进制...

    axis2客户端调用工程代码

    在IT行业中,Axis2是Apache软件基金会开发的一个用于构建Web服务和SOAP客户端的强大框架。它基于 Axis1,并提供了许多改进和新特性,使得在Java环境中处理Web服务变得更加简单。本篇将详细介绍如何在Axis2环境下编写...

    axis2客户端

    5. **服务托管**:除了客户端,Axis2还提供了服务端组件,可以方便地部署和管理Web服务。 6. **多种传输协议支持**:Axis2支持多种传输协议,如HTTP、HTTPS、SMTP等,使得Web服务可以跨越各种网络环境。 7. **集成...

    axis2客户端调用webService接口,精简jar包

    本文将深入探讨如何使用Axis2客户端调用WebService接口,并且会特别关注如何精简所需的jar包。 首先,了解Axis2客户端的基本概念是至关重要的。Axis2客户端是用于与远程Web服务交互的工具,它允许开发者通过SOAP...

    cxf客户端调用axis服务端流程

    本文将深入探讨如何使用CXF客户端调用Axis服务端的流程。 ### 一、了解CXF和Axis **CXF**(CXF: Composite eXtensible Framework)是一个开源的Java Web服务框架,它提供了多种方式来创建和使用Web服务,包括JAX-...

    AXIS2客户端调用实例

    在本文中,我们将深入探讨如何使用AXIS2客户端进行服务调用,包括AXIS2的基本概念、配置、服务引用以及调用流程。 **AXIS2简介** AXIS2是Apache软件基金会开发的一个强大的Web服务引擎,它支持多种协议,如SOAP 1.1...

    axis服务端和客户端创建

    ### Axis服务端与客户端创建详解 #### 一、概述 在深入探讨如何构建Apache Axis 1.4的服务端和客户端之前,我们先来了解一下相关的基础知识和技术背景。 **SOAP(Simple Object Access Protocol)**: 这是一种轻...

    axis2客户端调用带Ntlm认证例子

    解压后,仔细阅读文档,编译并运行示例代码,可以帮助你更好地理解如何在Axis2客户端中实现NTLM认证的Web服务调用。 总之,理解NTLM认证机制和如何在Axis2中使用它对于开发需要与Windows域集成的应用至关重要。通过...

    myeclipse8.5中axis2插件的安装和使用:axis2客户端代码生成

    Axis2 插件在 MyEclipse 8.5 中的安装和使用 Axis2 插件是 MyEclipse 8.5 中的一...通过使用 Axis2 插件,可以快速生成客户端代码,并实现服务的发布和调用。因此,Axis2 插件是 MyEclipse 8.5 中一个非常有用的插件。

Global site tag (gtag.js) - Google Analytics