1. 程式人生 > >呼叫WebService介面獲取資料

呼叫WebService介面獲取資料

在上一篇中寫了一個簡單了webservice,實現了一個sayHello功能。那麼webservice寫好之後我們如何使用Java程式來呼叫webservice呢?

一、java呼叫的webservice的第一種方式:RPC呼叫AXIS2 webservice
    下面這個方法是我抽象出來的一個方法,

複製程式碼
import javax.xml.namespace.QName;

import org.apache.axis2.AxisFault;
import org.apache.axis2.addressing.EndpointReference;
import org.apache.axis2.client.Options;
import org.apache.axis2.rpc.client.RPCServiceClient; public class Client { /** * @param args * @throws Exception */ public static void main(String[] args) throws Exception { // 呼叫PublishWebService String wsdlUrl = "http://localhost:8080/DigitalProduct/services/PublishWebService?wsdl";//webservice地址 String method
= "updatePublishSysParam"; //呼叫的那個方法 Object[] param = new Object[] { "AASSDDFF" };//傳遞的引數值 String namespaceUrl1 = "http://service.digitalproduct.tkbs.com";//名稱空間 Class[] opReturnType1 = new Class[] { String[].class };//返回值型別 String result = axis2RPCInvoke(wsdlUrl, method, param, namespaceUrl1,opReturnType1); System.out.println(result); }
/** * RPC呼叫AXIS2 webservice * * @param wsdlUrl * 服務地址 如:http://192.168.0.1:2597/aixs2/services/jqservice?wsdl * @param methodName * 方法名 如<xs:element name="Receive"> * @param parameter * 方法引數 如Object[] opArgs = new Object[] { param }; * @param namespaceURI * 名稱空間 如 :targetNamespace="http://server.test.com.cn"> * @param returnType * 返回型別 如字串:Class[] opReturnType = new Class[] { String[].class * }; */ public static String axis2RPCInvoke(String wsdlUrl, String methodName, Object[] parameter, String namespaceURI, Class[] returnType) { Object[] ret = null; RPCServiceClient serviceClient = null; try { /* * 此處RPCServiceClient 物件例項建議定義成類中的static變數 ,否則多次呼叫會出現連線超時的錯誤。 */ serviceClient = new RPCServiceClient(); Options options = serviceClient.getOptions(); EndpointReference targetEPR = new EndpointReference(wsdlUrl); options.setTo(targetEPR); QName opQName = new QName(namespaceURI, methodName); ret = serviceClient.invokeBlocking(opQName, parameter, returnType); // System.out.println(((String[]) ret[0])[0]); } catch (AxisFault e) { e.printStackTrace(); } return ((String[]) ret[0])[0]; } }
複製程式碼

二、使用java呼叫webservice的第二種方式:使用myeclipse中的axis2外掛生成客戶端程式碼

new –>others到如下介面:

    點next 到如下介面:

現在我們想生成呼叫webservice的客戶端程式碼,首先我們需要生成一個service.wsdl檔案,選擇第2個,點next,

在介面裡邊點選add folder 選擇專案–》webroot–》webinf–>classes,輸入好webservice那個類的全名後點擊Test Class Loading ,這時候如果你選擇的路徑是對的,類全名是對的,就可以點next,否則next按鈕式灰色的。如圖:

然後點選next,這個介面中的內容基本不用修改,有一個service name ,你可以改成你自己取。

繼續點next 在介面中選擇wsdl檔案的輸出路徑,選擇第一個,就是輸出到當前的workspace,的某個專案下,選擇第二個,就是輸出到系統資料夾中,例如你可以選擇桌面。

這裡我選擇第二個,然後點browse選擇桌面,點finish,會看到桌面上有一個service.wsdl檔案。

下面我們就可以根據這個wsdl檔案生成客戶端程式碼了。

首先建一個java專案,例如取名myclient

new –>others–>

選擇第1個,點next.

在介面中點 browse找到你剛才生成service.wsdl檔案。

點next,這個介面不用管,繼續點next

這個時候需要選擇程式碼生成的地方,選擇當前工作的workspace,然後選擇剛才新建的myclient如圖:

點finsh,重新整理myclient專案會看到src下多了兩個java檔案:TestServiceCallbackHandler   和 TestServiceStub

接下來就可以寫java程式碼呼叫了,如下:

複製程式碼
import myservice.service.TestServiceStub;

public class Test {

    /**
     * @param args
     * @throws Exception 
     */
    public static void main(String[] args) throws Exception {
        // TODO Auto-generated method stub
        //初始化Sub類
        TestServiceStub stub = new TestServiceStub();
        //傳遞AxisServiceStub.ShowName物件,相關引數在這邊賦值。
        TestServiceStub.SayHello command = new TestServiceStub.SayHello();
        command.setName("zhangsan");
        //取得返回值
        String name = stub.sayHello(command).get_return();
        System.out.println(name);
    }

}
複製程式碼

如此,第二種方式就寫完了。

公司幾個同事都喜歡第二種。但是,我個人喜歡用第一種。第二種方式如果外掛使用熟練的話,很快就可以生產客戶端程式碼,然後測試程式碼也可以很快寫出來。

注:可能會出現錯誤,根據我的經歷的錯誤經驗,有以下情況:

    1.tomcat埠問題,你開啟剛才插架自動生成的TestServiceStub 類 ctrl+f查詢 http://localhost,查到後看他後面的埠是多少,是不是8080,?好像生成的就是8080,但是我們的tomcat可能被自己修改過,埠可能不是8080,所以這裡你要改這個埠。

    2.spring的注入問題,如果你寫的webservice是在spring整合的環境下,可能會報錯誤,一般是由 spring注入失敗,導致xxxService類注入失敗。關於這個我下一篇會詳細解釋。

    3.一切都正常,打斷點除錯看到方法執行成功了、執行完畢了,但是並沒有成功的返回我們要的結果,而是報超時了,這時候,我們需要在TestServiceStub 中加入一行程式碼

        這行程式碼的作用是 規定超時時間 是多長,例如你可以設為10分鐘。_operationClient.getOptions().setTimeOutInMilliSeconds(600000L);  //600*1000毫秒(10分鐘

      我感覺這樣設定不合理,但是可以解決這個錯誤,讓你的程式執行成功,看到執行成功返回的結果。才有繼續學習的勁頭啊。