天天看點

使用axis2進行WebService的開發一、下載下傳與安裝二、服務端編寫三、用戶端編寫

使用axis2進行WebService的開發

Apache Axis2 是 Apache Axis SOAP 項目的後繼項目。此項目是 Web 服務核心引擎的重要改進,目标是成為 Web 服務和面向服務的體系結構(Service-Oriented Architecture,SOA)的下一代平台。

axis2 WebService開發分為服務端開發與用戶端開發,服務端開發為對外提供服務,用戶端開發為使用者調用外部接口進行業務處理。

一、下載下傳與安裝

1.下載下傳

下載下傳位址:http://axis.apache.org/axis2/java/core/download.cgi

有以下下載下傳清單:

Binary Distribution zip | MD5 | PGP 

Source Distribution zip | MD5 | PGP 

WAR Distribution zip | MD5 | PGP 

Documents Distribution zip | MD5 | PGP

注:

axis2-1.6.2-bin.zip裡有axis2的jar包。

axis2-1.6.2-docs.zip裡有詳細的幫助文檔。

axis2-1.6.2-src.zip裡是源代碼。

axis2-1.6.2-war.zip裡是axis的管理平台,放到tomcat可直接使用。

注:本文用bin包進行指令行使用axis2,管理平台使用的是war包。

2.安裝配置

将axis2-1.6.2-bin.zip解壓到本地目錄D:\axis2-1.6.2

設定環境變量。【注:前提需要配置java環境變量】

AXIS2_HOME 設定值 D:\axis2-1.6.2

Path 添加值 %AXIS2_HOME%\bin

二、服務端編寫

1.建立服務端的java項目testAsixServer。

編寫類City與類User代碼如下:

package com.hsinghsu.model;

public class City
{
    private int cityCode;

    private String cityName;

    public int getCityCode()
    {
        return cityCode;
    }

    public void setCityCode(int cityCode)
    {
        this.cityCode = cityCode;
    }

    public String getCityName()
    {
        return cityName;
    }

    public void setCityName(String cityName)
    {
        this.cityName = cityName;
    }

}
           
package com.hsinghsu.model;

public class User
{
    private int id;

    private String name;

    private String password;

    private City city;

    public int getId()
    {
        return id;
    }

    public void setId(int id)
    {
        this.id = id;
    }

    public String getName()
    {
        return name;
    }

    public void setName(String name)
    {
        this.name = name;
    }

    public String getPassword()
    {
        return password;
    }

    public void setPassword(String password)
    {
        this.password = password;
    }

    public City getCity()
    {
        return city;
    }

    public void setCity(City city)
    {
        this.city = city;
    }

}
           

編寫服務類UserService。該服務類即為對外提供的服務,其中對外提供2個服務getUserById與getUserList,代碼如下:

package com.hsinghsu.service;

import java.util.ArrayList;
import java.util.List;

import com.hsinghsu.model.User;

public class UserService
{
    public List<User> getUserList(User user)
    {
        List<User> list = new ArrayList<User>();

        return list;
    }

    public User getUserById(int id)
    {
        User user = new User();

        return user;
    }

}
           

2.釋出WebService服務

釋出WebService服務方式可使用axis2管理平台釋出,本文另添加使用soapUI釋出WebService的測試服務。

2.1 axis2管理平台釋出

2.1.1 部署axis2管理平台

将axis2-1.6.1-war.zip壓縮包裡面的axis2.war包解壓到tomcat的webapps目錄下,啟動tomcat,通路位址http://127.0.0.1:8080/axis2/ ,即可通路axis2的Welcome!頁面。

通路位址http://127.0.0.1:8080/axis2/services/listServices 另可通路服務清單。

2.1.2 部署開發服務

編譯服務端項目testAsixServer後,将UserService.class檔案放到tomcat\webapps\axis2\WEB-INF\pojo目錄中【注:若沒有pojo目錄,則手動建立該目錄】。

在浏覽器位址欄中輸入如下的URL:

http://127.0.0.1:8080/axis2/services/listServices 即可通路重新整理後的服務清單。【注:POJO類不能使用package關鍵字聲明包,若使用axis2管理平台釋出,則需要修改UserService類,去掉package字段。】

【注:釋出WebService的pojo目錄隻是預設的,如果想在其他的目錄釋出WebService,可以打開axis2/WEB-INF/conf/axis2.xml檔案,并在<axisconfig>元素中添加如下的子元素:

<deployer extension=".class" directory="mydir" class="org.apache.axis2.deployment.POJODeployer"/>】

通路 http://127.0.0.1:8080/axis2/services/UserService?wsdl 即可通路服務UserService的wsdl描述

【注:另可使用jar cvf指令将服務打成aar包後導入到axis2管理平台上使用。】

2.2 使用soapUI生成WAR釋出WebService測試服務

2.2.1 由java生成wsdl檔案

運用Java2wsdl生成wsdl檔案

使用cmd指令,在指令行中輸入:

java2wsdl -cn com.hsinghsu.service.UserService

【注:在testAsixServer項目的classes根目錄下執行】

輸出:

Using AXIS2_HOME:   D:\axis2-1.6.2

Using JAVA_HOME:    C:\Program Files\Java\jdk1.6.0_01

log4j:WARN No appenders could be found for logger (org.apache.axis2.util.Loader).

log4j:WARN Please initialize the log4j system properly.

結果:

生成UserService.wsdl檔案

2.2.2 soapUI導出war包:

在soapUI導入UserService.wsdl檔案。

通過soapUI生成MockService。

啟動MockService,測試MockService時,在URL填寫http://HSING-PC:8088/mockUserServiceSoap11Binding 後點選運作,檢視是否有正确封包傳回。

soapUI發送封包如下:

<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:ser="http://service.hsinghsu.com">
   <soapenv:Header/>
   <soapenv:Body>
      <ser:getUserById>
         <!--Optional:-->
         <ser:id>2</ser:id>
      </ser:getUserById>
   </soapenv:Body>
</soapenv:Envelope>
           

soapUI接收封包如下:

<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:ser="http://service.hsinghsu.com" xmlns:xsd="http://model.hsinghsu.com/xsd">
   <soapenv:Header/>
   <soapenv:Body>
      <ser:getUserByIdResponse>
         <!--Optional:-->
         <ser:return>
            <!--Optional:-->
            <xsd:city>
               <!--Optional:-->
               <xsd:cityCode>001</xsd:cityCode>
               <!--Optional:-->
               <xsd:cityName>wh</xsd:cityName>
            </xsd:city>
            <!--Optional:-->
            <xsd:id>1</xsd:id>
            <!--Optional:-->
            <xsd:name>hsinghsu</xsd:name>
            <!--Optional:-->
            <xsd:password>123456</xsd:password>
         </ser:return>
      </ser:getUserByIdResponse>
   </soapenv:Body>
</soapenv:Envelope>
           

在soapUI中導出war包,如testUser.war。

2.2.3 部署war包

将war包部署到tomcat目錄下。【注:需要修改war包裡面的WEB-INF/soapui/testUser-soapui-project.xml檔案引用wsdl檔案的路徑】

啟動tomcat,通路在war所在的路徑如 http://127.0.0.1:8080/testUser/mockUserServiceSoap11Binding?WSDL ,即可檢視wsdl描述檔案

【注:可以使用soapUI測試接口,在soapUI測試中,URL中填寫testUser.war的部署位址,如http://ip:port/testUser/mockUserServiceSoap11Binding ,點選運作,檢視對應的接口是否有正确封包傳回。】

三、用戶端編寫

Axis2支援以下4種類型的用戶端:

i.  Block(阻塞式用戶端),即傳統用戶端。一旦服務被啟用,用戶端的應用程式将被挂起,直到operation被執行完畢(表現為收到一個response或fault),才能重新獲得控制權。這是調用Web Service最簡單的方式,并且這種方式适用于多數業務情形。

ii. Non block(非阻塞式用戶端),即異步用戶端。使用Non-Blocking API來調用這些Web Services。Axis2提供給使用者一種基于回叫機制的non-blocking API,一旦服務被起用,用戶端應用程式馬上得到控制權,通過使用一個callback對象來獲得response。這種方式使得用戶端應用程式可以很友善的同步啟用多個Web Service。

iii.雙工(雙向傳輸)。以上的機制都使用單一的連接配接去發送請求和接收響應.這都明顯在性能上落後于使用兩條連接配接(單向或雙向)進行進行請求和響應的傳輸 . 是以以上的機制都不能解決長時間運作的交易, 連接配接将在操作還沒完成就會逾時. 一種解決方案是使用分開的兩條傳輸連接配接來傳輸請求和響應 . 我們叫這種方案為傳輸層異步。

iv. 雙工非阻塞(雙向且非阻塞傳輸)。

注:axis2 webservice client端需要的jar包有:

axis2-kernel-1.6.1.jar
axis2-adb-1.6.1.jar
axiom-api-1.2.12.jar
commons-logging-1.1.1.jar
wsdl4j-1.6.2.jar
XmlSchema-1.4.7.jar
axiom-impl-1.2.12.jar
neethi-3.0.1.jar
axis2-transport-local-1.6.1.jar
axis2-transport-http-1.6.1.jar
commons-httpclient-3.1.jar
httpcore-4.0.jar
commons-codec-1.3.jar
mail-1.4.jar 
           

1.傳統用戶端【阻塞式用戶端的編寫】

建立AsixBlockClient類,擷取資料,代碼如下:

package com.hsinghsu.asix.client;

import org.apache.axiom.om.OMAbstractFactory;
import org.apache.axiom.om.OMElement;
import org.apache.axiom.om.OMFactory;
import org.apache.axiom.om.OMNamespace;
import org.apache.axis2.AxisFault;
import org.apache.axis2.addressing.EndpointReference;
import org.apache.axis2.client.Options;
import org.apache.axis2.client.ServiceClient;

/**
 * 
 * Block(阻塞式用戶端),即傳統用戶端調用WebService Axis2的底層API來調用WebService
 * 
 * @author hsinghsu
 * 
 */
public class AsixBlockClient
{

    private static EndpointReference targetEPR = new EndpointReference(
            "http://127.0.0.1:8080/testUser/mockUserServiceSoap11Binding");//接口位址

    public static void main(String[] args)
    {
        Options options = new Options();
        options.setAction("urn:getUserById");//調用接口方法
        options.setTo(targetEPR);
        ServiceClient sender = null;
        try
        {
            sender = new ServiceClient();
            sender.setOptions(options);
            OMFactory fac = OMAbstractFactory.getOMFactory();
            OMNamespace omNs = fac.createOMNamespace(
                    "http://service.hsinghsu.com", "");
            OMElement method = fac.createOMElement("getUserById", omNs);
            OMElement name = fac.createOMElement("id", omNs);//設定入參名稱
            name.setText("1");//設定入參值
            method.addChild(name);
            method.build();
            System.out.println("method:" + method.toString());// print:<getUserById xmlns="http://service.hsinghsu.com"><id>1</id></getUserById>
            OMElement response = sender.sendReceive(method);
            System.out.println("response:" + response);
            OMElement elementReturn = response.getFirstElement().getFirstElement().getFirstElement();
            System.out.println("cityCode:"+elementReturn.getText());
        }
        catch (AxisFault e)
        {
            System.out.println("Error");
            e.printStackTrace();
        }

    }

}
           

執行結果如下:

method:<getUserById xmlns="http://service.hsinghsu.com"><id>1</id></getUserById>
response:<ser:getUserByIdResponse xmlns:ser="http://service.hsinghsu.com">
         <!--Optional:-->
         <ser:return>
            <!--Optional:-->
            <xsd:city xmlns:xsd="http://model.hsinghsu.com/xsd">
               <!--Optional:-->
               <xsd:cityCode>001</xsd:cityCode>
               <!--Optional:-->
               <xsd:cityName>wh</xsd:cityName>
            </xsd:city>
            <!--Optional:-->
            <xsd:id xmlns:xsd="http://model.hsinghsu.com/xsd">1</xsd:id>
            <!--Optional:-->
            <xsd:name xmlns:xsd="http://model.hsinghsu.com/xsd">hsinghsu</xsd:name>
            <!--Optional:-->
            <xsd:password xmlns:xsd="http://model.hsinghsu.com/xsd">123456</xsd:password>
         </ser:return>
      </ser:getUserByIdResponse>
cityCode:001
           

2.使用RPC方法調用WebService

編寫AsixRPCClient.java類,擷取資料。注:添加User.java、City.java至項目中。

AsixRPCClient.java代碼如下:

package com.hsinghsu.asix.client;

import javax.xml.namespace.QName;

import org.apache.axis2.addressing.EndpointReference;
import org.apache.axis2.client.Options;
import org.apache.axis2.rpc.client.RPCServiceClient;

import com.hsinghsu.model.User;

/**
 * 使用RPC方式調用WebService
 * 
 * @author hsinghsu
 * 
 */
public class AsixRPCClient
{

    /**
     * @param args
     */
    public static void main(String[] args) throws Exception
    {
        // 使用RPC方式調用WebService
        RPCServiceClient serviceClient = new RPCServiceClient();
        Options options = serviceClient.getOptions();

        EndpointReference targetEPR = new EndpointReference(
                "http://127.0.0.1:8080/testUser/mockUserServiceSoap11Binding");// 指定調用WebService的URL
        options.setTo(targetEPR);

        Object[] opAddEntryArgs = new Object[]{new Integer(1)};// 指定getGreeting方法的參數值

        Class[] classes = new Class[]{User.class};// 指定getGreeting方法傳回值的資料類型的Class對象

        QName opAddEntry = new QName("http://service.hsinghsu.com",
                "getUserById");// 指定要調用的getGreeting方法及WSDL檔案的命名空間
        Object[] objects = serviceClient.invokeBlocking(opAddEntry,
                opAddEntryArgs, classes);// RPCServiceClient類的invokeBlocking方法調用了WebService中的方法。invokeBlocking方法有三個參數,其中第一個參數的類型是QName對象,表示要調用的方法名;第二個參數表示要調用的WebService方法的參數值,參數類型為Object[];第三個參數表示WebService方法的傳回值類型的Class對象,參數類型為Class[]。當方法沒有參數時,invokeBlocking方法的第二個參數值不能是null,而要使用new Object[]{}。

        System.out.println(" objects size-->:" + objects.length);

        if (objects.length >= 1)
        {
            User user = new User();
            user = (User) objects[0];

            System.out.println("==" + user.getId() + " ==" + user.getName()
                    + " ==" + user.getCity().getCityName());
        }

    }

}
           

運作結果:

 objects size-->:1[Ljava.lang.Object;@ba5c7a

==1 ==hsinghsu ==wh

3.使用Stub方式調用WebService

運用wsdl2java簡化用戶端,使用Stub方式調用WebService

3.1 生成STUB檔案。

在cmd中用 wsdl2java生成stub檔案。注:在wsdl檔案目錄下執行

輸入:

wsdl2java -uri UserService.wsdl

【注:預設adb生成方式,同步生成方式,加參數-a則使用異步生成】

輸出:

Using AXIS2_HOME:   D:\axis2-1.6.2

Using JAVA_HOME:    C:\Program Files\Java\jdk1.6.0_01

Retrieving document at 'UserService.wsdl'.

log4j:WARN No appenders could be found for logger (org.apache.axis2.description.WSDL11ToAllAxisServicesBuilder).

log4j:WARN Please initialize the log4j system properly.

結果:

生成build.xml、UserServiceStub.java、UserServiceCallbackHandler.java檔案

3.2 編寫同步調用函數

編寫AsixServiceStub類,擷取資料。

AsixServiceStub.java代碼如下:

package com.hsinghsu.asix.client;

import com.hsinghsu.service.UserServiceStub;
import com.hsinghsu.service.UserServiceStub.GetUserById;
import com.hsinghsu.service.UserServiceStub.User;

/**
 * 利用axis2插件生成用戶端方式調用 wsdl2java簡化用戶端的編寫
 * 
 * @author hsinghsu
 * 
 */
public class AsixServiceStub
{

    public static void main(String[] args) throws Exception
    {

        UserServiceStub stub = new UserServiceStub();
        GetUserById guid = new GetUserById();
        guid.setId(1);
        User user = stub.getUserById(guid).get_return();// 同步調用方式

        if (null != user)
        {
            System.out.println("==" + user.getId() + " ==" + user.getName()
                    + " ==" + user.getCity().getCityName());
        }
        else
        {
            System.out.println("user null");
        }

    }

}
           

運作結果:

==1 ==hsinghsu ==wh

注:添加UserServiceStub.java、UserServiceCallbackHandler.java檔案至項目中,注意修改UserServiceStub.java類中服務的位址。

注:若需要使用異步調用,則需建立異步回調類AsynCallback,該類需要繼承UserServiceCallbackHandler抽象類,實作回調函數receiveResultgetUserById接口。在AsixServiceStub中,隻需要使用stub.startgetUserById(guid, new AsynCallback());執行即可。

web