WebService大讲堂之Axis2(2):复合类型数据的传递
- 格式:doc
- 大小:61.50 KB
- 文档页数:9
A XIS2之WEBSERVICE新手超详细教程---------------尚明Axis2是一套崭新的WebService引擎,该版本是对Axis1.x重新设计的产物。
Axis2不仅支持SOAP1.1和SOAP1.2,还集成了非常流行的REST WebService,同时还支持Spring、JSON 等技术,本教程是主要阐述如何构建一个基本的Axis2 webservice应用,里面的许多环节高手可直接略过,本教程完全针对新手。
一、环境安装安装myeclipse下载地址::///file/4238159/48030981-6b56-40a4-a93b-8f424ee4f33a安装mysql下载地址::///file/4238159/de64cf2f-4217-4e11-bb98-8e6c5dd24155安装mysql-workbench(mysql可视化工具)下载地址::///file/4238159/becf913f-56a6-4d68-b248-134113b73535安装tomcat下载地址::///file/4238159/ec6a2250-99ff-464e-a978-be184c96e4e7下载Axis2服务包下载地址::///file/4238159/bb3db6e3-2f7d-4343-b472-c1fa714dba95下载Axis2开发插件包下载地址::///file/4238159/aa39505f-079b-43be-9479-15a2d3e98cbb安装jdk下载地址::///file/4238159/7ba342f9-277f-4b9c-b5e7-b0c5b7dfc151二、环境配置1)Java环境配置a)设置JAVA_HOME图1.图2设置JAVA_HOME=D:\Program Files\Java\jdk1.6.0_10* D:\Program Files\Java\jdk1.6.0_10为笔者本机的JDK安装目录,请开发者根据实际安装路径来填写,注意环境变量最后面不能加分号,D:\Program Files\Java\jdk1.6.0_10;这么写是错误的。
A XIS2之WEBSERVICE新手超详细教程---------------尚明Axis2是一套崭新的WebService引擎,该版本是对Axis1.x重新设计的产物。
Axis2不仅支持SOAP1.1和SOAP1.2,还集成了非常流行的REST WebService,同时还支持Spring、JSON 等技术,本教程是主要阐述如何构建一个基本的Axis2 webservice应用,里面的许多环节高手可直接略过,本教程完全针对新手。
一、环境安装安装myeclipse下载地址::///file/4238159/48030981-6b56-40a4-a93b-8f424ee4f33a安装mysql下载地址::///file/4238159/de64cf2f-4217-4e11-bb98-8e6c5dd24155安装mysql-workbench(mysql可视化工具)下载地址::///file/4238159/becf913f-56a6-4d68-b248-134113b73535安装tomcat下载地址::///file/4238159/ec6a2250-99ff-464e-a978-be184c96e4e7下载Axis2服务包下载地址::///file/4238159/bb3db6e3-2f7d-4343-b472-c1fa714dba95下载Axis2开发插件包下载地址::///file/4238159/aa39505f-079b-43be-9479-15a2d3e98cbb安装jdk下载地址::///file/4238159/7ba342f9-277f-4b9c-b5e7-b0c5b7dfc151二、环境配置1)Java环境配置a)设置JAVA_HOME图1.图2设置JAVA_HOME=D:\Program Files\Java\jdk1.6.0_10* D:\Program Files\Java\jdk1.6.0_10为笔者本机的JDK安装目录,请开发者根据实际安装路径来填写,注意环境变量最后面不能加分号,D:\Program Files\Java\jdk1.6.0_10;这么写是错误的。
Axis2.x WebService上次介绍了axis1.x的用法,这次继续上次的,将叙述axis2的用法。
Axis1.x在线博文:/hoojo/archive/2010/12/20/1911349.html一、准备工作1、开发准备首先需要下载axis2的相关jar包,到axis的官方网站即可获得开发的依赖包。
下载地址:/axis2/java/core/download.cgi现在最高的版本是1.5.4的然后你需要下载官方提供的axis的eclipse插件工具,可以帮助我们打包(aar)及其生产客户端调用代码。
下载页面:/axis2/java/core/tools/index.htmlService Archive Wizard - Eclipse Plug-inCode Generator Wizard - Eclipse Plug-in2、安装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示例注意,上面的HelloWorldService是没有package的。
axis2实现WebService之复合类型数据的传递接着昨天的程序,今天又进了一步,学习了webservice 的复合类型数据的传递,尤其是教程上没有的部分,我自己尝试着写,虽说耗费了一个下午的时间,但是还是非常值的,废话少说,看招!在实际的应用中,不仅需要使用WebService来传递简单类型的数据,有时也需要传递更复杂的数据,这些数据可以被称为复合类型的数据。
数组与类(接口)是比较常用的复合类型。
在Axis2中可以直接使用将WebService方法的参数或返回值类型声明成数组或类(接口)。
但要注意,在定义数组类型时只能使用一维数组,如果想传递多维数组,可以使用分隔符进行分隔,如下面的代码所示:String[] strArray = new String[]{ "自行车,飞机,火箭","中国,美国,德国","超人,蜘蛛侠,钢铁侠" } ;上面的代码可以看作是一个3*3的二维数组。
在传递类的对象实例时,除了直接将数组类型声明成相应的类或接口,也可以将对象实例进行序列化,也就是说,将一个对象实例转换成字节数组进行传递,然后接收方再进行反序列化,还原这个对象实例。
下面的示例代码演示了如何传递数组与类(接口)类型的数据,并演示如何使用字节数组上传图像。
本示例的客户端代码使用Java编写。
要完成这个例子需要如下几步:一、实现服务端代码[java] view plaincopy<spanstyle="font-size:14px;">import java.io.FileOutputStream; import data.DataForm; public class ComplexTypeService { // 上传图像,imageByte参数表示上传图像文件的字节,// length参数表示图像文件的字节长度(该参数值可能小于imageByte的数组长度)public boolean uploadImageWithByte(byte[] imageByte, int length){ FileOutputStream fos = null; try{ // 将上传的图像保存在D盘的test1.jpg文件中fos = newFileOutputStream("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; } // 返回一维字符串数组public String[] getArray() { String[] strArray = new String[]{ "自行车", "飞机", "火箭" }; return strArray; } // 返回二维字符串数组public String[] getMDArray() { String[] strArray = new String[]{ "自行车,飞机,火箭","中国,美国,德国", "超人,蜘蛛侠,钢铁侠" } ; return strArray; } // 返回DataForm类的对象实例public DataForm getDataForm() { return newDataForm(); } // 将DataForm类的对象实例序列化,并返回序列化后的字节数组public byte[] getDataFormBytes() throws Exception{ java.io.ByteArrayOutputStream baos = newjava.io.ByteArrayOutputStream();java.io.ObjectOutputStream oos = newjava.io.ObjectOutputStream(baos);oos.writeObject(new DataForm()); return baos.toByteArray(); } } </span>二、实现DataForm类[java] view plaincopy<spanstyle="font-size:14px;">package data; public class DataForm implements java.io.Serializable { private String name = "bill"; private int age = 20; setter…………getter方法} </span>三、发布WebService由于本示例的WebService类使用了一个Java类(DataForm类),因此,在发布WebService之前,需要先将DataForm.class文件复制到<Tomcat安装目录>\webapps\axis2\WEB-INF\classes\data目录中,然后将ComplexTypeService.class文件复制到<Tomcat安装目录>\webapps\axis2\WEB-INF\pojo目录中,最后启动Tomcat (如果Tomcat已经启动,由于增加了一个DataForm类,因此,需要重新启动Tomcat)。
WebService大讲堂之Axis2(4):二进制文件传输在《WebService大讲堂之Axis2(2):复合类型数据的传递》中讲过,如果要传递二进制文件(如图像、音频文件等),可以使用byte[]作为数据类型进行传递,然后客户端使用RPC方式进行调用。
这样做只是其中的一种方法,除此之外,在客户端还可以使用wsdl2java命令生成相应的stub类来调用WebService,wsdl2java命令的用法详见《WebService大讲堂之Axis2(1):用POJO实现0配置的WebService》。
WebService类中包含byte[]类型参数的方法在wsdl2java生成的stub类中对应的数据类型不再是byte[]类型,而是javax.activation.DataHandler。
DataHandler类是专门用来映射WebService二进制类型的。
在WebService类中除了可以使用byte[]作为传输二进制的数据类型外,也可以使用javax.activation.DataHandler作为数据类型。
不管是使用byte[],还是使用javax.activation.DataHandler作为WebService方法的数据类型,使用wsdl2java命令生成的stub类中相应方法的类型都是javax.activation.DataHandler。
而象使用.net、delphi生成的stub类的相应方法类型都是byte[]。
这是由于javax.activation.DataHandler类是Java特有的,对于其他语言和技术来说,并不认识javax.activation.DataHandler类,因此,也只有使用最原始的byte[]了。
下面是一个上传二进制文件的例子,WebService类的代码如下:package service;import java.io.InputStream;import java.io.OutputStream;import java.io.FileOutputStream;import javax.activation.DataHandler;public class FileService{// 使用byte[]类型参数上传二进制文件public boolean uploadWithByte(byte[] file, String filename){FileOutputStream fos = null;{fos = new FileOutputStream(filename);fos.write(file);fos.close();}catch (Exception e){return false;}finally{if (fos != null){try{fos.close();}catch (Exception e){}}}return true;}private void writeInputStreamToFile(InputStream is, OutputStream os) throws Exception {int n = 0;byte[] buffer = new byte[8192];while((n = is.read(buffer)) > 0)os.write(buffer, 0, n);}}// 使用DataHandler类型参数上传文件public boolean uploadWithDataHandler(DataHandler file, String filename) {FileOutputStream fos = null;try{fos = new FileOutputStream(filename);// 可通过DataHandler类的getInputStream方法读取上传数据writeInputStreamToFile(file.getInputStream(), fos);fos.close();}catch (Exception e){return false;}finally{if (fos != null){try{fos.close();}catch (Exception e){}}}return true;}}上面代码在services.xml文件的配置代码如下:<service name="fileService"><description>文件服务</description><parameter name="ServiceClass">service.FileService</parameter><messageReceivers><messageReceiver mep="/2004/08/wsdl/in-out"class="org.apache.axis2.rpc.receivers.RPCMessageReceiver"/></messageReceivers></service>如果使用wsdl2java命令生成调用Java客户端代码,则需要创建DataHandler类的对象实例,代码如下:DataHandler dh = new DataHandler(new FileDataSource(imagePath));wsdl2java命令会为每一个方法生成一个封装方法参数的类,类名为方法名(第一个字符大写),如uploadWithByte方法生成的类名为UploadWithByte。
目录一、背景介绍二、Webservice数据传输原理三、数据断点续传的概念四、Webservice数据断点续传的实现原理五、总结一、背景介绍随着互联网和移动互联网的不断发展,大量的数据需要在网络中进行传输。
在传输过程中,由于网络环境等原因,数据传输可能会发生中断,导致数据无法完整传输。
为了解决这一问题,数据断点续传技术应运而生。
本文将重点介绍Webservice数据断点续传原理及实现方法。
二、Webservice数据传输原理Webservice是一种基于XML和HTTP协议传输的数据交换格式,它是一种跨评台、跨语言的通信协议。
在Webservice中,数据的传输是通过HTTP协议进行的,采用标准的HTTP请求和响应进行数据交互。
数据传输过程中,客户端向服务端发送请求,服务端接收到请求后返回数据给客户端。
三、数据断点续传的概念数据断点续传是指在数据传输过程中,如果由于网络问题或其他原因导致传输中断,可以通过某种方法实现数据的续传,而不需要重新传输整个文件。
这种技术能够提高数据传输的效率,节省网络带宽,并且能够保证数据的完整性。
四、Webservice数据断点续传的实现原理1.断点续传的实现需要在客户端和服务端都进行相应的处理。
在Webservice中,数据的传输是通过HTTP协议进行的,因此可以利用HTTP协议的特性来实现断点续传。
2.客户端首先发送一个HTTP请求到服务端,请求数据的起始位置。
服务端接收到请求后,返回相应的数据给客户端。
3.客户端接收数据后,将数据保存在本地,并记录已经接收到的数据大小。
4.如果数据传输中断,客户端可以再次发送一个HTTP请求到服务端,请求从上次中断的位置继续传输数据。
服务端接收到请求后,返回上次中断位置开始的数据给客户端。
5.客户端接收到数据后,将数据追加到上次保存的位置,并更新已经接收到的数据大小。
6.重复以上步骤,直到数据传输完成。
通过以上实现步骤,可以在Webservice中实现数据的断点续传。
WebService流行框架之Axis和CXF前言上节课我们对WebService进行了简单的介绍,对于其所应用到的技术有了一定的了解。
今天主要讲解下WebService的两个流行的框架Axis和CXF。
正题一、服务端发布WebService在讲解之前,我们先来看一下这篇博客主要讲解的内容:每一种框架都有自己的特点,有自己的侧重,但是他们的共同之处在于对发布WebService进行了封装,所以我们只需编写一个配置文件或者使用@WebService注解就可以发布WebService,我们这里着重说一下他们各自的特点:1.Axis1Axis1有两种发布方式:1)JWS方式a.这种方式很简单,只需要将源码java文件放到AXIS_HOME下面,然后将后缀改为.jws,这样,Axis 会自动编译.jws文件,并把它自动加入到Java WebServie的服务中。
b.但是这种方式的缺点是:只能是java源代码,同时类中不能含有包名。
2)WSDD方式1.写一个java类(需要引入axis的jar包)2.配置web.xml文件(配置AxisServlet,AdminServlet,SOAPMonitorService和AxisHTTPSessionListener)3.写一个deloy.wsdd文件,部署项目(tomcat启动就可以部署项目)安装axis1到tomcat:1.Axis官方网站:/axis/,可以在官网下载最新1.4的包:axis-bin-1_4.zip2.将解压后的axis-1_4\webapps\下的axis目录考到%TOMCAT_HOME%/Webapps/目录下3.启动tomcat后在浏览器里输入http://localhost:port/axis4.点击上图中的Validataion链接,页面上会提示已经有的包和缺少的包的信息,根据提示将必须的包下载全,将这些类包复制到%tomcathome%/webapps/axis/WEB-INF/lib/目录下重新启动tomcat,直到Validation页面中看不到有Error与Warning的提示信息。
AXIS2系列教程Axis2是目前比较流行的WebService引擎。
WebService被应用在很多不同的场景。
例如,可以使用WebService来发布服务端Java类的方法,以便使用不同的客户端进行调用。
这样可以有效地集成多种不同的技术来完成应用系统。
WebService还经常被使用在SOA中,用于SOA各个部分交换数据。
本课程重点讲解了Axis2的核心功能,并提供了三个项目以使学员理解并掌握如何将Axis2应用于不同的场景。
本课程站在初学者角度介绍了Axis2的大多数常用的功能,例如,以多种方式编写和发布WebService、JAX-RPC、JAX-WS、复杂类型传输、WebService会话管理、Axis2模块等。
本课程共分为两部分,其中第一部分为Axis2基础知识讲解。
在这部分介绍了前面所述的Axis2 知识。
第二部分介绍了三个小的项目。
这三个项目的功能类似。
所不同的是,它们使用了不同的技术来实现。
第一个项目使用Java Swing 技术实现了个人信息管理(PIM)系统,这个系统可以对个人信息(如姓名、职位、电话等)进行增、删、改、查。
在这些操作中,涉及到了如何使用WebService来传输和下载图像文件、传输查询结果(Resultset 对象)等技术难点。
第二个项目使用Struts 2.1.6(目前Struts 2的最新版,2009年1月发布)来实现PIM。
功能与第一个PIM类似。
只是这个系统为Web版。
在这个项目中学员可以学习到如果将WebService应用在Web程序中。
该系统的主要思想是如果Web程序和WebService部署在同一台机器上,Web程序可以直接调用WebService所对应的Java类。
当然,也可以象第一个项目一样,直接通过HTTP SOAP协议调用WebService。
在第二个项目中同时使用了这两种方式来实现。
这两种调用方式分别封装在两组Model类中。
可以通过配置struts.xml文件来提定使用哪组模型类(调用方式)。
WebService大讲堂之Axis2(2):复合类型数据的传递在实际的应用中,不仅需要使用WebService来传递简单类型的数据,有时也需要传递更复杂的数据,这些数据可以被称为复合类型的数据。
数组与类(接口)是比较常用的复合类型。
在Axis2中可以直接使用将WebService方法的参数或返回值类型声明成数组或类(接口)。
但要注意,在定义数组类型时只能使用一维数组,如果想传递多维数组,可以使用分隔符进行分隔,如下面的代码所示:String[] strArray = new String[]{ "自行车,飞机,火箭","中国,美国,德国", "超人,蜘蛛侠,钢铁侠" } ;上面的代码可以看作是一个3*3的二维数组。
在传递类的对象实例时,除了直接将数组类型声明成相应的类或接口,也可以将对象实例进行序列化,也就是说,将一个对象实例转换成字节数组进行传递,然后接收方再进行反序列化,还原这个对象实例。
下面的示例代码演示了如何传递数组与类(接口)类型的数据,并演示如何使用字节数组上传图像。
本示例的客户端代码使用Java和C#编写。
要完成这个例子需要如下几步:一、实现服务端代码ComplexTypeService是一个WebService类,该类的代码如下:import java.io.FileOutputStream;import data.DataForm;public class ComplexTypeService{// 上传图像,imageByte参数表示上传图像文件的字节,// length参数表示图像文件的字节长度(该参数值可能小于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;}// 返回一维字符串数组public String[] getArray(){String[] strArray = new String[]{ "自行车", "飞机", "火箭" };return strArray;}// 返回二维字符串数组public String[] getMDArray(){String[] strArray = new String[]{ "自行车,飞机,火箭","中国,美国,德国", "超人,蜘蛛侠,钢铁侠" } ;return strArray;}// 返回DataForm类的对象实例public DataForm getDataForm(){return new DataForm();}// 将DataForm类的对象实例序列化,并返回序列化后的字节数组public byte[] getDataFormBytes() throws Exception{java.io.ByteArrayOutputStream baos = new java.io.ByteArrayOutputStream();java.io.ObjectOutputStream oos = new java.io.ObjectOutputStream(baos);oos.writeObject(new DataForm());return baos.toByteArray();}}二、实现DataForm类DataForm是要返回的对象实例所对应的类,该类的实现代码如下:package data;public class DataForm implements java.io.Serializable{private String name = "bill";private int age = 20;public String getName(){return name;}public void setName(String name){ = name;}public int getAge(){return age;}public void setAge(int age){this.age = age;}}三、发布WebService由于本示例的WebService类使用了一个Java类(DataForm类),因此,在发布WebService之前,需要先将DataForm.class文件复制到<Tomcat安装目录>\webapps\axis2\WEB-INF\classes\data目录中,然后将ComplexTypeService.class文件复制到<Tomcat安装目录>\webapps\axis2\WEB-INF\pojo目录中,最后启动Tomcat(如果Tomcat已经启动,由于增加了一个DataForm类,因此,需要重新启动Tomcat)。
四、使用Java编写调用WebService的客户端代码在客户端仍然使用了RPC的调用方式,代码如下:package client;import space.QName;import org.apache.axis2.addressing.EndpointReference;import org.apache.axis2.client.Options;import org.apache.axis2.rpc.client.RPCServiceClient;public class ComplexTypeRPCClient{public static void main(String[] args) throws Exception{RPCServiceClient serviceClient = new RPCServiceClient();Options options = serviceClient.getOptions();EndpointReference targetEPR = new EndpointReference("http://localhost:8080/axis2/services/ComplexT ypeService");options.setTo(targetEPR);// 下面的代码调用uploadImageWithByte方法上传图像文件/////////////////////////////////////////// 打开图像文件,确定图像文件的大小java.io.File file = new java.io.File("f:\\images.jpg");java.io.FileInputStream fis = new java.io.FileInputStream("f:\\images.jpg");// 创建保存要上传的图像文件内容的字节数组byte[] buffer = new byte[(int) file.length()];// 将图像文件的内容读取buffer数组中int n = fis.read(buffer);System.out.println("文件长度:" + file.length());Object[] opAddEntryArgs = new Object[]{ buffer, n };Class[] classes = new Class[]{ Boolean.class };QName opAddEntry = new QName("/axis2","uploadImageWithByte"); fis.close();// 开始上传图像文件,并输出uploadImageWithByte方法的返回传System.out.println(serviceClient.invokeBlocking(opAddEntry,opAddEntryArgs, classes)[0]);/////////////////////////////////////////// 下面的代码调用了getArray方法,并返回一维String数组/////////////////////////////////////////opAddEntry = new QName("/axis2", "getArray");String[] strArray = (String[]) serviceClient.invokeBlocking(opAddEntry,new Object[]{}, new Class[]{String[].class })[0];for (String s : strArray)System.out.print(s + " ");System.out.println();/////////////////////////////////////////// 下面的代码调用了getMDArray方法,并返回一维String数组/////////////////////////////////////////opAddEntry = new QName("/axis2", "getMDArray");strArray = (String[]) serviceClient.invokeBlocking(opAddEntry, new Object[]{},new Class[]{String[].class})[0];for (String s : strArray){String[] array = s.split(",");for(String ss: array)System.out.print("<" + ss + "> ");System.out.println();}System.out.println();/////////////////////////////////////////// 下面的代码调用了getDataForm方法,并返回DataForm对象实例/////////////////////////////////////////opAddEntry = new QName("/axis2", "getDataForm");data.DataForm df = (data.DataForm) serviceClient.invokeBlocking(opAddEntry, new Object[]{},new Class[]{data.DataForm.class})[0];System.out.println(df.getAge());/////////////////////////////////////////// 下面的代码调用了getDataFormBytes方法,并返回字节数组,最后将返回的字节数组反序列化后,转换成DataForm对象实例/////////////////////////////////////////opAddEntry = new QName("/axis2", "getDataFormBytes");buffer = (byte[]) serviceClient.invokeBlocking(opAddEntry, new Object[]{}, new Class[]{byte[]. class})[0];java.io.ObjectInputStream ois = new java.io.ObjectInputStream(new java.io.ByteArrayInputStream(buffer));df = (data.DataForm) ois.readObject();System.out.println(df.getName());//////////////////////////////////////////}}运行上面的程序,将输出如下的内容:文件长度:3617true自行车飞机火箭<自行车> <飞机> <火箭><中国> <美国> <德国><超人> <蜘蛛侠> <钢铁侠>20bill五、使用C#编写调用WebService的客户端代码在Visual Studio中使用WebService就简单得多。