转:http://blog.csdn.net/ziapple/archive/2007/05/19/1616736.aspx
WSDL:Web Service Description Language
环境:Tomcat5.0.28+Axis1.4+MyEclipse6.5
Ax 一、Axis 三种开发方式 Axis(Apache extensible Interaction system) 是Apache项目组织的一个开源项目。前身是Apache SOAP,它通过如下方法来扩展了soap2.0的功能: AXIS 的关键功能和优势表现在速度(早期的SOAP的分析机制是基于DOM的,而AXIS是基于SAX的),灵活性(提供了在引擎中插入新扩展的功能,可以对头部信息的处理和系统管理进行定制,在WSDD中对服务,Handler对象和串行并行程序进行描述),面向组件展开(引入了链接chainable和 Handler的概念),传输框架(SOAP可以建立在SMTP, FTP, HTTP等多种传输层协议上)。 Axis 支持三种web service的部署和开发,分别为: 1、Dynamic Invocation Interface ( DII) 2、Dynamic Proxy方式 3、Stubs方式
对于前两种 Web Service的发布基本一样,客户端的访问也很类似,第一种发布就是直接将.java后缀改为.jws,并将生成的.class文件拷贝到WEB- INF/jwsclasses下面,这样的例子直接在Axis上就有,非常简单,但它也有缺陷,就是不适合程序部署和大型项目开发,而且不支持包(package)的形式(这个只是我的个人见解),第三种是目前比较流行的方式,stub意思是树桩,意味着服务端和客户端都是通过桩的形式来完成访问的,即在服务端将java转换成wsdl,在客户端将wsdl装换成java,这样就实现了良好的桩的分离。
二、 Dynamic Invocation Interface ( DII)开发方式
1. 在Eclipse里新建一个Tomcat Project取名为testaxis,在接下来的工程中我们也统一用这一工程来演示。 2. 接着是部署Axis所必须的步骤 将axis-1_4/webapps/axis中几个必须的文件拷贝到你的AxisTest工程文件下,一个是WEB-INF/lib下的所有文件,一个是WEB-INF下面的web.xml文件,我们来简单看一下web.xml这个文件
<servlet> <servlet-name>AxisServlet</servlet-name> <display-name>Apache-Axis Servlet</display-name> <servlet-class> org.apache.axis.transport.http.AxisServlet </servlet-class> </servlet> <servlet-mapping> <servlet-name>AxisServlet</servlet-name> <url-pattern>/servlet/AxisServlet</url-pattern> </servlet-mapping> <servlet-mapping> <servlet-name>AxisServlet</servlet-name> <url-pattern>*.jws</url-pattern> </servlet-mapping> <servlet-mapping> <servlet-name>AxisServlet</servlet-name> <url-pattern>/services/*</url-pattern> </servlet-mapping>
就是说如果向容器请求/servlet/AxisServlet、*.jws、/services/*这几种映射会引起调用AxisServlet这个类,我们要用的就这几行,其他的可以直接删掉。
3. 在WEB-INF/src下面新建一个myService.java文件,如下public class myService { public String getusername(String name){ return "Hello "+name+",this is an Axis DII Web Service"; } } 注意这个java文件是不属于任何package的,如果你要将其放入某个package那么Axis会提示你找不到它生成的class文件从而不能将其转换为wsdl文件。 4. 将myService.java拷贝到AxisTest根目录下,将其后缀改为jws。
5. 启动Tomcat输入http://localhost:8089/testaxis/myService.jws?wsdl,点击Click to see the WSDL,如果看到如下界面就表示你已经成功发布一个Web Service了,就这么简单,如果出现错误就表示你的配置错误,或者是你的web.xml有问题,或者是你的包引用有问题,多试几遍这个问题很容易搞定的,这个一定要正确,不然接下来的客户端就访问不到了,这时候你会在WEB-INF下面看到Axis会自动生成一个jwsClasses文件夹,jwsClasses下面会有一个myService.class文件。
6. 接下来是编写客户端来访问这个getService,在com.axistest包下新建一个myServiceTestorByjws.java,代码如下: /*** */package com.axistest; import java.net.MalformedURLException;import java.rmi.RemoteException; import javax.xml.rpc.ParameterMode; import javax.xml.rpc.ServiceException; import org.apache.axis.client.Call; import org.apache.axis.client.Service; import org.apache.axis.encoding.XMLType; public class myServiceTestorByjws { public static void main(String[] args) throws ServiceException, MalformedURLException, RemoteException { String endpoint="http://localhost:8089/testaxis/myService.jws"; String name="毛毛"; Service service = new Service(); Call call = (Call) service.createCall(); call.setTargetEndpointAddress(new java.net.URL(endpoint)); call.addParameter("param1",XMLType.XSD_STRING,ParameterMode.IN); call.setOperationName( "getusername" ); call.setReturnType( XMLType.XSD_STRING ); String ret = (String) call.invoke( new Object[] { name } ); System.out.println("返回结果:" + ret); } } 7. 运行结果:返回结果:Hello 毛毛,this is an Axis DII Web Service
三二、 Dynamic Proxy 方式,WSDD方式 动态代理就是通过 wsdd 来描述 Web 服务,而不是直接访问 jws ,前面说过 jws 是不支持包的,而且运行也不稳定,有时候可以访问有时候就不可以,所以不推荐此种方法, wsdd 和 wsdl 的区别在于前者只描述 Web 服务和操作方法以及传输方式,它相对于 wsdl 要简单的多,更易被人读懂。为此我们需要作如下工作:
1. 为了更好的区分,我们将myService放入com.service包下,这就是WSDD的好处,它不像DII不能建包,并修改代码如下
package com.service; public class MyserviceDP {public String getusername(String name){ return "Hello "+name+",this is an Axis Dynamic Proxy Web Service"; }} 2. 在 WEB-INF 下新建一个 server-config.wsdd 文件,代码如下:
<deployment xmlns="http://xml.apache.org/axis/wsdd/" xmlns:java="http://xml.apache.org/axis/wsdd/providers/java"><handler type="java:org.apache.axis.handlers.http.URLMapper" name="URLMapper"/> <service name="myService" provider="java:RPC"> <parameter name="className" value="com.service.MyserviceDP"/> <parameter name="allowedMethods" value="getusername"/> </service><transport name="http"><requestFlow> <handler type="URLMapper"/></requestFlow></transport></deployment> 3. 测试发布的 myService, 重启 Tomcat ,在浏览器输入
http://localhost:8089/testaxis/servlet/AxisServlet;如果出现如下界面表示你的Web Service发布成功( 点 myServiceDP (wsdl) )
4. 接下来写客户端代码,在 com.axistest 下新建一个 myServiceTestorByWSDD.java ,代码如下:
package com.axistest;import java.net.MalformedURLException;import java.rmi.RemoteException;import javax.xml.rpc.ServiceException;import org.apache.axis.client.Call;import org.apache.axis.client.Service;public class myServiceTestorByWSDD {public static void main(String[] args) throws ServiceException,MalformedURLException, RemoteException { String endpoint = "http://localhost:8089/testaxis/services/myServiceDP"; Service service = new Service(); // 创建一个Service实例,注意是必须的! Call call = (Call) service.createCall(); // 创建Call实例,也是必须的! call.setTargetEndpointAddress(new java.net.URL(endpoint));// 为Call设置服务的位置 call.setOperationName("getusername"); // 注意方法名与JavaBeanWS.java中一样!! String res = (String) call.invoke(new Object[] { "毛毛" }); // 返回String,传入参数 System.out.println(res);}} 注意上述方法和 jws 方式唯一的不同就在于 endpoint 的引用方式不同,一个是直接引用 jws 文件,一个是引用一个 wsdd 描述的服务。
5. 运行结果:Hello 毛毛,this is an Axis Dynamic Proxy Web Service
三、 Stubs 方式 这种实现方式是目前比较流行的方式,他将用于发布服务的提供商和用于引用服务的应用商有效的实现了分离,而且较之于前两种开发方法, Stubs 不需要程序员关注 WebService 的返回类型,也就是不用我们去关心 wsdl ,因为他是 axis 自动生成的,例如 webservice 要返回一个 Stirng[] 类型, axis 自动将其转化为 Array ,调用也简单。这种方式是在 EJB 基础上发展起来的,熟悉 EJB 的人应该很熟悉这种方式,所以 stubs 方式是这几种开发方式中最成熟的方法,下面是步骤: 1. 在 testaxis 根目录下建立一个 java2wsdl 文件夹,在 java2wsdl 文件夹下新建一个名为 build.xml 的 Ant 构建,内容如下:<?xml version="1.0" encoding="UTF-8"?><project name="Generate WSDL from JavaBeans as Web Services" default="j2w-all" basedir="."> <property name="build.dir" value="../../WebRoot/WEB-INF/classes"/> <property name="axis.dir" location="D:/Downloads/axis-src-1_4/axis-1_4"/> <path id="classpath.id"> <fileset dir="${axis.dir}/lib"> <include name="*.jar"/> </fileset> <pathelement location="${build.dir}"/> </path><taskdef name="axis-java2wsdl" classname="org.apache.axis.tools.ant.wsdl.Java2WsdlAntTask" loaderref="axis" > <classpath refid="classpath.id"/></taskdef> <target name="j2w-all"> <antcall target="j2w-JavaBeanWS"/> </target> <target name="j2w-JavaBeanWS"> <axis-java2wsdl classname="com.service.MyServiceDP" classpath="${build.dir}" methods="getusername" output="myService.wsdl" location="http://localhost:8089/testaxis/services/myServiceDP" namespace="http://localhost:8089/testaxis/services/myServiceDP" namespaceImpl="http://localhost:8089/testaxis/services/myServiceDP"> </axis-java2wsdl> </target></project> 关于 Ant 构建的语法请参考相关文章,简单说一下一个是 axis.dir ,就是你下载的 Axis-1.4 的目录,一个是 <target name="j2w-JavaBeanWS"> , classname 表示你的 myService 存放的路径, methods 表示 webservice 中的方法,方法名称必须和 myService 中的方法一致,否则即使构建成功了也不能执行, output 是输出的 wsdl 名称,locat location 是 myService 的访问地址,用于客户调用, namespace 是命名空间,有了命名空间你就可以通过namespace .webservice 的方法来调用这个 webservice ,好了,关于 Ant 构建就介绍到这里。 2. 运行 Ant 构建,在 java2wsdl 目录下会自动生成一个 myService.wsdl 的文件。 3. 下面开始客户端的工作,客户端就是把服务端的 wsdl 文件转换为 java 文件以便于客户端的调用执行,理论上服务端和客户端是分离的,他们属于不同的系统和项目,两者毫无相干,唯一联系他们的是 wsdl ,但我们为了方便都放在 AxisTest 项目中,客户端的做法是将发布商发布的 wsdl 文件拷贝到自己的项目中,在这里我们已经有了这个 wsdl 就可以省去这一步,在testaxis 新建一个源文件夹( Source Folder ),注意是源文件夹不是文件夹,取名为 wsdl2java ,新建一个 build.xml 的 Ant 构建,内容如下:
<?xml version="1.0" encoding="UTF-8"?><project name="wsclient" default="all" basedir="."><property name="axis.home" location="D:/Downloads/axis-src-1_4/axis-1_4"/><property name="options.output" location="../wsdl2java"/><path id="axis.classpath"> <fileset dir="${axis.home}/lib"> <include name="**/*.jar"/> </fileset></path><taskdef resource="axis-tasks.properties" classpathref="axis.classpath" /><target name="-WSDL2Axis" depends="init"> <mkdir dir="${options.output}"/> <axis-wsdl2java output="${options.output}" url="${options.WSDL-URI}" verbose="true"/></target><target name="init"> <echo>Warning: please update the associated WSDL file(s) in the folder wsdl before running the target!</echo> <echo>Warning: Just run the target(s) related with your developing work!</echo> <echo></echo></target><target name="all"> <antcall target="myService"/> </target><target name="myService"> <antcall target="-WSDL2Axis"> <param name="options.WSDL-URI" location="../src/java2wsdl/myService.wsdl"/> </antcall></target> </project> 4. 运行 Ant 构建,运行结果如下: 这是在 wsdl2java 文件夹会自动生成几各类,别看Axis自动生成这么多类,其实都很简单,我们真正实际用到的就*ServiceLocator.java和*.java类,ServiceLocator是获得webservice的定位,*.java是具体实现类。
5. 编写客户端测试代码,在com.axistest新建一个myServiceTestorByStubs.java,内容如下:
package com.axistest;import localhost.testaxis.services.myServiceDP.MyServiceDPServiceLocator;import localhost.testaxis.services.myServiceDP.MyServiceDP;
public class myServiceTestorByStubs { public static void main(String[] args) throws Exception { MyServiceDPServiceLocator Service= new MyServiceDPServiceLocator(); MyServiceDP port= Service.getmyServiceDP(); String response=port.getusername("毛毛"); System.out.println(response); } }
运行结果:Hello 毛毛,this is an Axis Dynamic Proxy Web Service(当然这里的“Dynamic Proxy ”就不准确了。)
工程结构如下: