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文件。

 

axis1.4与myeclipse开发webservice_java
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) )

axis1.4与myeclipse开发webservice_客户端_02

 

 

 

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名称,locatlocation是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 ”就不准确了。)

 

工程结构如下:

 

axis1.4与myeclipse开发webservice_.net_03