1. 程式人生 > >WEBSERVICE發布與調用

WEBSERVICE發布與調用

ati output ddp target rda reat 重寫 框架 補丁

一.背景說明

最近在做一個任務,主要目的就是將客戶SAP系統裏的RFC函數發布成WebService,並在我們的前置機程序裏面調用,得到返回的數據並經過解析處理後按照和原有邏輯類似的方式去處理。

二.具體操作

可以知道問題的關鍵在於WebService的發布與調用。因為之前在EBS系統裏面部署配置過Intergrated soa gateway,並發布過Webservice接口。所以對相關概念有一定的了解,這次正好趁這個機會,算是重新加深一波理解了。這裏主要記錄下,過程中了解到的一些相關的東西以及問題。本文暫時只討論soap協議的webservice。

2.1 Webservice發布

SAP裏的Webservice發布可以參考: http://www.cnblogs.com/zohoo/p/7295920.html

對比來說,可能是因為EBS版本問題,感覺比EBS裏的Webservice發布要簡單,因為至少不用再去自己部署集成soa網關了,也就不用再去自己打一些相關的數據庫及應用補丁了。但是因為這個工作主要由公司的SAP顧問完成,他們沒弄好,我這邊不可能一直幹等著啊,所以先簡略的用Java發布個Webservice以用於調用測試,再對比來說,Java直接發布Webservice比SAP裏更加的簡單,方式有很多,盡量用簡單的。主要就兩個註解:類上加上@WebService,要發布的方法上加上@WebMethod。具體參考:
https://www.cnblogs.com/redjh/p/6841665.html

2.2 Webservice調用

Java裏關於Webservice的調用方式也是很多。這裏只說我用到的幾個,其他的如什麽CXF,wsimport等需要用到的時候再細說。關鍵是在於從他們之中提取共同點,這些才是最基礎最重要的東西。也就是所謂的Webservice三要素:WSDL,SOAP,UUDI,另外還有我們永遠繞不開的HTTP。但我們這裏概念先不去細說,有需要可以去搜索了解下,還是先看看用法。
(1). 使用axis2的wsdl2java直接生成調用類
wsdl2java -uri ./gen_wsdl/zws_apdoc1.wsdl -p com.zqx.test -o feedback
這種方式其實類似於wsimport,這裏的uri可以是本地也可以是遠程wsdl地址,-p 指定包名,- o指定生成代碼路徑。以上命令可能會給你生成類似於這樣的兩個java文件:

調用方式可能就是類似於下面這樣。這也是我要說的這種方式的問題所在了,你必須找到你wsdl裏面定義的傳入傳出參數類型和他生成的類裏面的什麽對應,這樣才好去調用這個service獲得response。好處在於,如果你足夠熟練的話,可以按自己的需要去重寫生成的類以滿足自己的需求,比如在調用過程中加一些寫日誌的代碼,以方便出問題時好調試定位錯誤。

    //服務
    ZWS_APDOC1Stub service = new ZWS_APDOC1Stub();
    //參數
    ZWS_APDOC1Stub.ZhscfApdocE params = new ZWS_APDOC1Stub.ZhscfApdocE();
    ZWS_APDOC1Stub.Date10 arg0 = new ZWS_APDOC1Stub.Date10();
    arg0.setDate10("2015-02-01");
    ZWS_APDOC1Stub.Numeric2 arg1 = new ZWS_APDOC1Stub.Numeric2();
    arg1.setNumeric2("7");
    ZWS_APDOC1Stub.TableOfZhscfApdoc arg2 = new ZWS_APDOC1Stub.TableOfZhscfApdoc();
    //arg2.setItem();
    params.setIDate(arg0);
    params.setIDays(arg1);
    params.setTHead(arg2);
    ZWS_APDOC1Stub.ZhscfApdocResponse response = service.zhscfApdoc(params);
    ZWS_APDOC1Stub.ZhscfApdoc[] items = response.getTHead().getItem();

    System.out.println(":"+ JSONObject.toJSONString(response));

    for (int i = 0; i <items.length ; i++) {
        System.out.println(i+":"+ JSONObject.toJSONString(items[i]));
    }
   

(2). 使用HttpURLConnection直接調用
這個在.NET裏類似的東西好像叫做HttpWebRequest,不同的平臺不同叫法,本質其實還是一樣的東西。這種方式就相對原始了,但不知道為什麽,可能是從C語言裏養成的習慣,天生對這種東西有莫名的好感。因為盡管可能繁瑣一點,但不用被所謂的”框架”遮蔽雙眼了,各有利弊吧。使用方式可能就類似於這樣:

public static String doPost(String url, String params) {
    try {
        HttpURLConnection conn = (HttpURLConnection) new URL(url).openConnection();
        conn.setRequestMethod("POST");
        conn.setDoOutput(true);
        conn.setDoInput(true);
        // 超時時間30秒
        int timeout = 30 * 1000;
        conn.setConnectTimeout(timeout);
        conn.setReadTimeout(timeout);
        //add by zhuqingxin <begin>
        //conn.setRequestProperty("Content-Type","text/xml");
        conn.setRequestProperty("Content-Type","text/xml; charset=UTF-8");
        //conn.setRequestProperty("Content-Type","application/json; charset=UTF-8");
        //add by zhuqingxin <end>
        conn.connect();
        if (params != null) {
            OutputStreamWriter out = new OutputStreamWriter(conn.getOutputStream(), CHARSET_NAME);
            out.write(params);
            out.flush();
            out.close();
        }
        InputStreamReader r = new InputStreamReader(conn.getInputStream(), CHARSET_NAME);
        BufferedReader reader = new BufferedReader(r);
        String line;
        StringBuffer sb = new StringBuffer();
        while ((line = reader.readLine()) != null) {
            sb.append(line);
        }
        return sb.toString();
    } catch (IOException e) {
        return null;
    }
}

註意下這裏的url可以就是我們的wsdl鏈接,但是params參數需要是一個完整的soap請求報文,怎麽獲得這個報文呢?如果你足夠熟悉wsdl,可以直接用字符串拼接的方式去構造,不熟的話就可以用工具幫你自動生成了,比如有個叫storm的軟件,或者用我們最常用的soapUI:

(3). 使用axis的rpc調用方式
以前我一直覺得,至少在Java裏,這種方式是最簡單方便的。自從經歷了這次的問題之後,我才發現以前的想法還是太簡單,了解的東西還是太淺薄。這個後面說,依舊還是先看看用法:

 private static void testhello() throws Exception{
    String endpoint = "http://localhost:9000/hello?wsdl";
    String namespace = "http://zqx.com/";
    // 直接引用遠程的wsdl文件
    // 以下都是套路
    Service service = new Service();
    Call call = (Call) service.createCall();
    call.setTargetEndpointAddress(endpoint);
    // WSDL裏面描述的接口名稱(要調用的方法)
    call.setOperationName(new QName(namespace,"sayHello"));
    call.addParameter("arg0", XMLType.XSD_STRING, ParameterMode.IN);// 接口的參數
    call.setReturnType(XMLType.XSD_STRING);// 設置返回類型
    call.setEncodingStyle(namespace);
    String result = (String )call.invoke(new Object[]{"測試人員"});
    System.out.println(result);

}           

三. 參考

https://blog.csdn.net/qq_31763083/article/details/53812208
https://blog.csdn.net/menghuanzhiming/article/details/78489527
https://bbs.csdn.net/topics/392013286
https://www.cnblogs.com/luoxf/p/5881970.html
https://blog.csdn.net/sisierda/article/details/52998888
http://tieba.baidu.com/p/1913611121

WEBSERVICE發布與調用