Tomcat+Axis+Eclipse实例讲解

一、一、     声明
写这篇文章完全得益于梁爱虎的《精通SOA基于服务总线的整合应用开发》和一些关于axis开发web service的文章,对于什么是web service,我建议大家去看看EJB的东西,对web service有很好的理解,言归正传,下面开始实际的开发。
二、   环境配置
在这里,我不得不谈环境的配置,因为Java本身是一个开源的架构,这导致各个厂商各自开发自己的东西,升级也不一致,笔者写这篇文章之前是想用Weblogic8.1作为应用服务器的,但终究因版本的问题和Weblogic本身的复杂性而导致很多例子无法在其上运行,所以最终还是放弃了Weblogic的使用,版本不一致很容易就莫名奇怪的运行不起来,笔者只能保证下面的配置绝对没有问题,这里我采用的版本是
1. JDK1.5.0.6
2. Tomcat5.5 (好像5.0及以前的版本运行WebService有点问题)
3. Axis1.4
4. Eclipse3.1.2+MyEclipse 4.1.1GA_E3.1
变量设置:
变量设置是为了当你不用IDE例如Eclipse,你只是简单的通过JDK+Tomcat来完成你的工作时,需要Tomcat解析你的程序(你或者可以不通过变量设置而是直接将需要引用的类放在%TOMCAT_HOME%/common/lib下),当然如果你采用IDE来运行你的程序是,这一步是没有必要的,因为你可以同过添加类的方法来完成这一功能。下面是我的环境配置:
1. AXIS_HOME
D:/Java/axis-1_4 (这是我的Axis路径)
2. AXIS_LIB
%AXIS_HOME%/lib
3. AXIS_CLASSPATH
%AXIS_LIB%/axis.jar;%AXIS_LIB%/commons-discovery-0.2.jar;%AXIS_LIB%/commons-logging-1.0.4.jar;%AXIS_LIB%/jaxrpc.jar;%AXIS_LIB%/saaj.jar;%AXIS_LIB%/log4j-1.2.8.jar;%AXIS_LIB%/xml-apis.jar;%AXIS_LIB%/xercesImpl.jar;%AXIS_LIB%/wsdl4j-1.5.1.jar;%AXIS_LIB%/activation.jar;%AXIS_LIB%/xmlrpc-2.0.jar
4. CLASSPATH
.;%JAVA_HOME%/lib/tools.jar;%JAVA_HOME%/lib/dt.jar; %AXIS_CLASSPATH%;
5. 在你的%TOMCAT_HOME%/common/lib下需要加入三个包 activation.jar、mail.jar、tools.jar,注意这三个包是必须的,尽管tools.jar很常见,但这也是运行Axis所必须的包。
三、      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,这样就实现了良好的桩的分离,笔者会一一介绍。我在梁先生那部著作中只看到第一种和第三种的介绍,梁先生陈之为基于JavaBean的Web Service开发和基于无状态会话Bean的Web Service开发,后者主要是EJB的内容,可见Stubs的具体功用。
四、      Dynamic Invocation Interface ( DII) 开发方式
1. 在Eclipse里新建一个Tomcat Project取名为AxisTest,在接下来的工程中我们也统一用这一工程来演示。
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. 引用Axis包,由于我们添加了环境变量,所以用DII方法引用Axis包这一步可以省略掉,不过为了以后我们的其他方法引用,我们还是将这些包引用一下。
4. 整个环境部署如下图
图一
5. 在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文件。
6. 将myService.java拷贝到AxisTest根目录下,将其后缀改为jws。
7. 启动Tomcat输入 http://localhost:8080/AxisTest/myService.jws,会看到如下界面:
图二
8. 点击Click to see the WSDL,如果看到如下界面就表示你已经成功发布一个Web Service了,就这么简单,如果出现错误就表示你的配置错误,或者是你的web.xml有问题,或者是你的包引用有问题,多试几遍这个问题很容易搞定的,这个一定要正确,不然接下来的客户端就访问不到了,这时候你会在WEB-INF下面看到Axis会自动生成一个jwsClasses文件夹,jwsClasses下面会有一个myService.class文件。
图三
Wsdl的具体含义就不用我解释了吧,在我的博客里都有详细的介绍。
9. 接下来是编写客户端来访问这个getService,在com.axistest包下新建一个myServiceTestorByjws.java,选中public static void main(),如下图
图四
代码如下:
public static void main(String[] args) throws ServiceException, MalformedURLException, RemoteException {
             String endpoint="http://localhost:8080/AxisTest/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);
             }
10.              运行结果如下:
图五
注意第一行,Axis告诉我们缺少 activation mail类,是因为笔者没有引用这两个类,添加引用即可。
五、      Dynamic Proxy 方式,WSDD方式
动态代理就是通过 wsdd 来描述 Web 服务,而不是直接访问 jws ,前面说过 jws 是不支持包的,而且运行也不稳定,有时候可以访问有时候就不可以,所以笔者不推荐此种方法, wsdd wsdl 的区别在于前者只描述 Web 服务和操作方法以及传输方式,它相对于 wsdl 要简单的多,更易被人读懂。为此我们需要作如下工作:
1.       为了更好的区分,我们将 myService 放入 com.service 包下,这就是 WSDD 的好处,它不像 DII 不能建包 , 并修改代码如下:
package com.service;
public class myService {
public String getusername(String name){
        return "Hello "+name+",this is an Axis 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.myService"/>
        <parameter name="allowedMethods" value="getusername"/>
    </service>
<transport name="http">
 <requestFlow>
    <handler type="URLMapper"/>
 </requestFlow>
</transport>
</deployment>
这就是 WSDD 的全部内容,它描述一个 Web Service 发布。
3.       测试发布的 myService, 重启 Tomcat ,在浏览器输入
http://localhost:8080/AxisTest/servlet/AxisServlet ;如果出现如下界面表示你的 Web Service 发布成功
图六
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 tatic void main(String[] args) throws ServiceException,MalformedURLException, RemoteException {
        String endpoint = "http://localhost:8080/AxisTest/services/myService";
        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.       运行结果如图:
图七
六、      Stubs 方式
这种实现方式是目前比较流行的方式,他将用于发布服务的提供商和用于引用服务的应用商有效的实现了分离,而且较之于前两种开发方法, Stubs 不需要程序员关注 WebService 的返回类型,也就是不用我们去关心 wsdl ,因为他是 axis 自动生成的,例如 webservice 要返回一个 Stirng[] 类型, axis 自动将其转化为 Array ,调用也简单。这种方式是在 EJB 基础上发展起来的,熟悉 EJB 的人应该很熟悉这种方式,所以 stubs 方式是这几种开发方式中最成熟的方法,下面是步骤:
1.  AxisTest 根目录下建立一个 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="../WEB-INF/classes"/>
      <property name="axis.dir" location="D:/Java/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.myService" classpath="${build.dir}"
                    methods="getusername"
                        output="myService.wsdl"
                        location="http://localhost:8080/AxisTest/services/myService"
                        namespace="http://localhost:8080/AxisTest/services/myService"
                        namespaceImpl="http://localhost:8080/AxisTest/services/myService">        
          </axis-java2wsdl>
    </target>
</project>
关于 Ant 构建的语法请参考相关文章,简单说一下一个是 axis.dir ,就是你下载的 Axis-1.4 的目录,一个是 <target name="j2w-JavaBeanWS"> classname 表示你的 myService 存放的路径, methods 表示 webservice 中的方法,方法名称必须和 myService 中的方法一致,否则即使构建成功了也不能执行, output 是输出的 wsdl 名称, location myService 的访问地址,用于客户调用, namespace 是命名空间,有了命名空间你就可以通过 namespace.webservice 的方法来调用这个 webservice ,好了,关于 Ant 构建就介绍到这里。
2.  运行 Ant 构建,在 java2wsdl 目录下会自动生成一个 myService.wsdl 的文件,运行结果如下
图八
3.  下面开始客户端的工作,客户端就是把服务端的 wsdl 文件转换为 java 文件以便于客户端的调用执行,理论上服务端和客户端是分离的,他们属于不同的系统和项目,两者毫无相干,唯一联系他们的是 wsdl ,但我们为了方便都放在 AxisTest 项目中,客户端的做法是将发布商发布的 wsdl 文件拷贝到自己的项目中,在这里我们已经有了这个 wsdl 就可以省去这一步,在 AxisTest 新建一个源文件夹( 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:/Java/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="../java2wsdl/myService.wsdl"/>
    </antcall>
 </target>         
</project>
4.  运行 Ant 构建,运行结果如下:
图九
这是在 wsdl2java 文件夹会自动生成几各类,至此, Stubs 的整个结构目录如下:
图十
别看Axis自动生成这么多类,其实都很简单,我们真正实际用到的就*ServiceLocator.java和*.java类,ServiceLocator是获得webservice的定位,*.java是具体实现类。
5.  编写客户端测试代码,在 com.axistest 新建一个 myServiceTestorByStubs.java ,内容如下:
package com.axistest;
import localhost.AxisTest.services.myService.MyService;
import localhost.AxisTest.services.myService.MyServiceServiceLocator;
public class myServiceTestorByStubs {
       public static void main(String[] args) throws Exception
    {
        MyServiceServiceLocator Service= new MyServiceServiceLocator();
        MyService port= Service.getmyService();
        String response=port.getusername(" 邹萍 ");
        System.out.println(response);
    } 
}
 
  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值