Axis 開發WebService

一、環境準備
1 、從axis網站下載相關內容:http: //apache.justdn.org/ws/axis/1_3/ 
2 、解壓後,參考webapps\axis,爲了使你的web應用axis開發web service,需要做的事情如下: 
     a. 將webapps\axis\WEB- INF\lib下的相關jar包拷貝到你自己web應用的lib目錄下。另外需要activation.jar、 mail.jar兩個支持包。
     b.修改web.xml,加載axis的servlet。
< listener> 
< listener- class > org.apache.axis.transport.http.AxisHTTPSessionListener< / listener- class > 
< / listener> 
< 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> 

二、開發service
服務器端的service爲普通的java類:com.hnisi.axis.BookOrder

public class BookOrder {
public String getName(String name) {
System.out.println("start execute ..." );
return "book name: " + name;
}

public Book setPrice(Book book){
book.setPrice(10 );
return book;
}
}
com.hnisi.axis.Book爲簡單的值對象,包含兩個屬性name,price。
三、發佈service
1 、手工修改server- config.wsdd文件(在已有server- config.wsdd文件的情況下)
添加service:
< service name= "BookOrder" provider= "java:RPC" > 
< parameter name= "allowedMethods" value= "*" / > 
< parameter name= "className" value= "com.hnisi.axis.BookOrder" / > 
< / service> 
allowedMethods是調用的服務的方法,如果有多個方法的話可以用空格分開,當用* 的時候表示全部。

2 、寫deploy.wsdd文件,使用axis提供的AdminClient工具,自動生成server- config.wsdd。deploy.wsdd文件如下:
< deployment xmlns= "http://xml.apache.org/axis/wsdd/" 
xmlns: java= "http://xml.apache.org/axis/wsdd/providers/java" > 
< service name= "BookOrder" provider= "java:RPC" > 
< parameter name= "className" value= "com.hnisi.axis.BookOrder" / > 
< parameter name= "allowedMethods" value= "*" / > 
< / service> 
< / deployment> 
deploy.wsdd文件位於/ web- inf目錄下。
使用AdminClient發佈該service,在/ web- inf目錄下新建deploy.bat文件: 
set LIB_HOME= ./ lib
set CPATH= .;% LIB_HOME% \axis.jar;% LIB_HOME% \jaxrpc.jar;% LIB_HOME% \commons- logging- 1 .0 .2 .jar;% LIB_HOME%\commons- discovery- 0 .2 .jar;% LIB_HOME% \saaj.jar;% LIB_HOME% \activation.jar;% LIB_HOME% \mail.jar
java - classpath % CPATH% org.apache.axis.client.AdminClient - lhttp: //localhost:8080/test/services/AdminService deploy.wsdd 
pause
執行deploy.bat,會生成server- config.wsdd文件。成功生成的幾個必要條件:
a. axis相關jar包存在於/ web- inf/ lib下
b. 你的tomcat必須啓動,同時留意deploy.bat文件的第三行"http://localhost:8080/test/services/AdminService" ,根據具體情況修改。
否則會報"java.net.ConnectException: Connection refused: connect" 異常。
綜合上述,在第一次發佈service的情況下,需用方式2 生成server- config.wsdd,後續開發過程中,使用方式1 直接修改server-config.wsdd文件。
發佈後,執行http: //localhost:8080/test/services,能看到當前web應用的所有web service. 
http: //localhost:8080/test/services/BookOrder?wsdl 爲ServerService對應WSDL. 
還可以通過IE瀏覽器直接調用服務,方法是在服務URL後加"method=xxx" ,其中xxx是要調用的方法名稱: 
http: //localhost:8080/test/services/BookOrder?method=getName&name=HH 

四、調用service
有兩種方式可以調用service。
1 、使用org.apache.axis.client.Call直接調用

package com.hnisi.axis;

import org.apache.axis.client.Call;
import org.apache.axis.client.Service;

public class CallService {
public static void main(String[] args) {
try {
String endpoint = "http://localhost:8080/test/services/BookOrder" ; 
Service service = new Service();
Call call = (Call) service.createCall();

call.setTargetEndpointAddress( new java.net.URL(endpoint) );
call.setOperationName("getName" );

String ret = (String) call.invoke(new Object[] {"yehailong" });
System.out.println("return value is " + obj[0 ]);
catch (Exception ex) {
ex.printStackTrace();
}
}
}

2 、根據wsdl生成客戶端java代碼
/ web- inf目錄下新建make.bat文件: 

set LIB_HOME= ./ lib
set CPATH= .;% LIB_HOME% \axis.jar;% LIB_HOME% \jaxrpc.jar;% LIB_HOME% \commons- logging- 1 .0 .2 .jar;% LIB_HOME%\commons- discovery- 0 .2 .jar;% LIB_HOME% \saaj.jar;% LIB_HOME% \activation.jar;% LIB_HOME% \mail.jar;% LIB_HOME%\wsdl4j- 1 .5 .1 .jar;% LIB_HOME% \log4j- 1 .2 .6 .jar;./ classes

java - classpath % CPATH% org.apache.axis.wsdl.WSDL2Java - p com.hnisi.axis.client http://192.168.3.42:8080/test/services/BookOrder?wsdl 

pause


生成java代碼在包com.hnisi.axis.client下面,封裝了調用的接口。

然後,使用以上生成的java代碼,編寫調用service的測試類com.hnisi.axis.client.CallService: 

package com.hnisi.axis.client;

public class CallService {
public static void main(String[] args) {
try {
BookOrderService service = new BookOrderServiceLocator();
BookOrder_PortType client = service.getBookOrder();
String retValue = client.getName("zhangsan" );
System.out.println(retValue);
catch (Exception e) {
System.err.println("Execution failed. Exception: " + e);
}
}
}

五、對象的序列化和返序列化
在以上代碼的基礎上,試圖調用BookOrder的setPrice服務,會報這樣的異常:
faultString: java.io.IOException: No serializer found for class com.hnisi.axis.Book in registry

由於SOAP中值的類型就是XML Schema中的基本類型,默認只支持簡單類型和數組。所以在進行對象傳遞的過程中,需要進行序列化和反序列化。
Axis爲提供了大量的序列化/ 反序列化器,能夠基本滿足大部分應用:
1 、基本類型,如int double 等,轉換成基本對象類型java.lang.Integer、java.lang.Double。
2 、常用集合對象的轉換
java.util.List == > java.lang.Object[]
java.util.Vector == > java.util.Vector
3 、普通JavaBean(簡單值對象)的序列化和反序列化
首先,在web service部署端,修改server- config.wsdd文件,在具體的service配置,增加如下代碼:
< beanMapping languageSpecificType= "java:com.hnisi.axis.Book" qname= "ns1:Book" 
         xmlns: ns1= "urn:BeanService" / > 
languageSpecificType屬性指定JavaBean類文件位置,qname屬性指定JavaBean類的名字。當然,一個service可以綁定多個bean對象。

其次,在客戶端,完成對象的註冊。
對於調用方法一中,需要新增如下代碼以完成註冊:
QName qn = new QName("urn:BeanService" ,"Book" ); 
call.registerTypeMapping(Book.class , qn,
new BeanSerializerFactory(Book.class , qn),
                    new BeanDeserializerFactory(Book.class , qn));
而對於調用方法二,重新根據wsdl生成java代碼,已完成必要的對象註冊過程,CallService中可以直接傳遞Book對象了。
4 、複雜java對象的序列化
需要自行開發一個序列化/ 反序列化器,請參考http: //kb.csdn.net/java/Articles/200506/73d6aea4-0d38-4e21-a188-473790c9ef57.html 

六、axis和spring的集成
spring容器管理的業務層服務bean,可以做爲web service發佈。整合的方法有兩種:
1 、直接發佈
將spring容器中預定義的service直接做爲web service對外發布。
爲此,web服務的提供類必須有spring管理,在調用web服務時需要從web應用環境(ServletContext)中去獲取服務類的bean實例。
具體的實現原理請參考http: //blog.csdn.net/liumyong/archive/2004/12/09/210043.aspx 
2 、間接發佈
spring業務層servcie不直接做爲web service對外發布,提供一箇中間的接口(類)來調用spring service。
對外發布成web service的接口需要從Axis的contextAxis得到Spring的contextSpring:
        HttpServlet servlet = (HttpServlet) MessageContext.getCurrentContext().getProperty(HTTPConstants.MC_HTTP_SERVLET);
        ApplicationContext context = WebApplicationContextUtils.getWebApplicationContext(servlet.getServletContext());

以上兩種方式各有優缺點:
方式1 :
需要繼承擴展axis的相關代碼,重載實現org.apache.axis.transport.http.AxisServlet,並提供一個 SpringBeanProvider類來處理web service bean與spring service bean的關聯。
優點是,spring service直接做爲web service發佈,直接配置,無需任何附加中間接口。
方式2 :
需要爲每個web service提供一箇中間接口來調用spring service。
在單一的spring service不能滿足web服務需求時,可使用中間接口類綜合調用多個spring service,然後集中做爲一個web service發佈出去。

綜合上述,在實際的開發過程中,結合具體的應用靈活採取

七、Document/ Literal 樣式 
前文所使用的都是RPC/ ENCODED樣式發佈service,axis根據一定的規則完成JAVA對象和XML文件的轉化,即序列化和反序列化過程。
採用此方式,發佈和調用的過程都很簡單,服務發佈方和調用方都是直接面向JAVA對象,而其缺點也相當明顯: 
客戶端需要使用服務器端的輔助JAVA對象(儘管這些JAVA代碼可以自動根據WSDL生成),服務提供者和客戶之間的緊密耦合,任何對接口的更改都會導致服務和客戶間聯繫的中斷。

Document樣式和上面的RPC樣式最主要的不同就是,前者中客戶在一個規範的XML文檔中向服務器發送服務參數,而代替了後者中的一組離散的方法的參數值。這使得Document樣式比RPC樣式有更加鬆散的耦合關係。
Web服務提供者處理規範的XML文檔,執行操作並向客戶端作出響應,返回的也是一個規範的XML文檔。在服務器對象(參數,方法調用等)和XML數據值之間並沒有一種直接的映射關係。應用程序負責映射XML數據值。
Document樣式中SOAP消息在它的SOAP體中包含了一個或者更多的XML文檔。協議並沒有約束文檔需要如何組織構成;這完全是在程序級處理的。另外,Document樣式web服務遵循異步處理範例。

八、安全性問題
參考《實現安全的AXIS Web服務》。

九、開發工具
1 、ant支持
2 、eclipse wtp

http://yangzb.iteye.com/blog/256890

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章