Tomcat+Axis+Eclipse實例講解

一、聲明

 
寫這篇文章完全得益於樑愛虎的《精通SOA基於服務總線的整合應用開發》和一些關於axis開發web service的文章,對於什麼是web service,我建議大家去看看EJB的東西,對web service有很好的理解,言歸正傳,下面開始實際的開發。
 
二、環境配置
 
在這裏,我不得不談環境的配置,因爲Java本身是一個開源的架構,這導致各個廠商各自開發自己的東西,升級也不一致,筆者寫這篇文章之前是想用Weblogic8.1作爲應用服務器的,但終究因版本的問題和Weblogic本身的複雜性而導致很多例子無法在其上運行,所以最終還是放棄了Weblogic的使用,版本不一致很容易就莫名奇怪的運行不起來,筆者只能保證下面的配置絕對沒有問題,這裏我採用的版本是
1JDK1.5.0.6
2Tomcat5.5(好像5.0及以前的版本運行WebService有點問題)
3Axis1.4
4Eclipse3.1.2+MyEclipse 4.1.1GA_E3.1
變量設置:
變量設置是爲了當你不用IDE例如Eclipse,你只是簡單的通過JDK+Tomcat來完成你的工作時,需要Tomcat解析你的程序(你或者可以不通過變量設置而是直接將需要引用的類放在%TOMCAT_HOME%\common\lib下),當然如果你採用IDE來運行你的程序是,這一步是沒有必要的,因爲你可以同過添加類的方法來完成這一功能。下面是我的環境配置:
1AXIS_HOME
D:\Java\axis-1_4(這是我的Axis路徑)
2AXIS_LIB
%AXIS_HOME%\lib
3AXIS_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
4CLASSPATH
.;%JAVA_HOME%\lib\tools.jar;%JAVA_HOME%\lib\dt.jar; %AXIS_CLASSPATH%;
5.在你的%TOMCAT_HOME%\common\lib下需要加入三個包 activation.jarmail.jartools.jar,注意這三個包是必須的,儘管tools.jar很常見,但這也是運行Axis所必須的包。
三、Axis三種開發方式
Axis(Apache extensible Interaction system)Apache項目組織的一個開源項目。前身是Apache SOAP,它通過如下方法來擴展了soap2.0的功能:
AXIS的關鍵功能和優勢表現在速度(早期的SOAP的分析機制是基於DOM的,而AXIS是基於SAX),靈活性(提供了在引擎中插入新擴展的功能,可以對頭部信息的處理和系統管理進行定製,在WSDD中對服務,Handler對象和串行並行程序進行描述),面向組件展開(引入了鏈接chainableHandler的概念),傳輸框架(SOAP可以建立在SMTP, FTP, HTTP等多種傳輸層協議上)
Axis支持三種web service的部署和開發,分別爲:
  1Dynamic Invocation Interface ( DII)
  2Dynamic Proxy方式
  3Stubs方式
對於前兩種Web Service的發佈基本一樣,客戶端的訪問也很類似,第一種發佈就是直接將.java後綴改爲.jws,並將生成的.class文件拷貝到WEB-INF/jwsclasses下面,這樣的例子直接在Axis上就有,非常簡單,但它也有缺陷,就是不適合程序部署和大型項目開發,而且不支持包(package)的形式(這個只是我的個人見解),第三種是目前比較流行的方式,stub意思是樹樁,意味着服務端和客戶端都是通過樁的形式來完成訪問的,即在服務端將java轉換成wsdl,在客戶端將wsdl裝換成java,這樣就實現了良好的樁的分離,筆者會一一介紹。我在樑先生那部著作中只看到第一種和第三種的介紹,樑先生陳之爲基於JavaBeanWeb Service開發和基於無狀態會話BeanWeb 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輸入[url]http://localhost:8080/AxisTest/myService.jws[/url],會看到如下界面:
圖二
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告訴我們缺少activationmail類,是因爲筆者沒有引用這兩個類,添加引用即可。
五、      Dynamic Proxy方式,WSDD方式
動態代理就是通過wsdd來描述Web服務,而不是直接訪問jws,前面說過jws是不支持包的,而且運行也不穩定,有時候可以訪問有時候就不可以,所以筆者不推薦此種方法,wsddwsdl的區別在於前者只描述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,在瀏覽器輸入
[url]http://localhost:8080/AxisTest/servlet/AxisServlet[/url];如果出現如下界面表示你的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.xmlAnt構建,內容如下:
<?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名稱,locationmyService的訪問地址,用於客戶調用,namespace是命名空間,有了命名空間你就可以通過namespace.webservice的方法來調用這個webservice,好了,關於Ant構建就介紹到這裏。
2 運行Ant構建,在java2wsdl目錄下會自動生成一個myService.wsdl的文件,運行結果如下
圖八
3 下面開始客戶端的工作,客戶端就是把服務端的wsdl文件轉換爲java文件以便於客戶端的調用執行,理論上服務端和客戶端是分離的,他們屬於不同的系統和項目,兩者毫無相干,唯一聯繫他們的是wsdl,但我們爲了方便都放在AxisTest項目中,客戶端的做法是將發佈商發佈的wsdl文件拷貝到自己的項目中,在這裏我們已經有了這個wsdl就可以省去這一步,在AxisTest新建一個源文件夾(Source Folder),注意是源文件夾不是文件夾,取名爲wsdl2java,新建一個build.xmlAnt構建,內容如下:
<?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> 
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); 
    }  

結束語
至此,Tomcat+Axis+Eclipse實戰講解已全部結束,接下來筆者要做自己的畢設了,我的畢設是基於SSOA的動態供應鏈的研究,這個一時也說不明白,WebService只是筆者畢設的一小塊,筆者準備把Ontology加進去,Ontology的研究在國內還算是很新的,筆者研究了近兩個月現在毫無收穫,還望高人指點迷津。
 

本文出自 “鄒潤茨” 博客,請務必保留此出處http://ziapple.blog.51cto.com/271886/55512

發佈了17 篇原創文章 · 獲贊 5 · 訪問量 6萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章