WebService客戶端終極總結 + httpClient調用webservice


WebService概念簡單理解

1.可以看成是RPC的一種實現。常見的RPC框架:Dubbox、gRPC、Thrift、Avro等

2.wsdl:定義了服務端的接口的調用方式,包括請求和返回的類型等。

3.soap:采用Http來傳輸信息,可以認為是SOAP協議包裝了Http協議在TCP上傳輸。

4.wsdl與soap的關系在於:

 wsdl綁定服務的時候可以設定使用的協議,協議可以是soap、http、smtp、ftp等任何一種傳輸協議。

5.wsdl文件:其實封裝了wsdl和soap。

6.WebService優勢:

   語言無關

   獲取wsdl文件就知道怎么調用。

   技術成熟,可以直接通過工具生成客戶端。

 

WebService調用方式

1.通過URL Connection調用

 優點:僅僅是能實現

 缺點:使用原生類,太復雜了。發送Http請求和SOAP協議都要自己封裝。

2.通過wximport生成代碼

 優點:自動生成客戶端調用代碼,不用實現。

     因為生成的是代碼,直接調用類即可。

 缺點:會生成很多類。

3.axis2、cxf、xFire等框架。

 優點:比較成熟,也能自動生成客戶端調用代碼。

     因為生成的是代碼,直接調用類即可。

 缺點:引入重量級框架,也會生成很多類。

     當然,如果系統的WebService通訊很多,那么可以考慮。

4.HttpClient調用(本文推薦)

 優點:封裝了Http請求,一般系統都有jar,不需要引入額外的jar包。

     不會生成很多類,代碼簡潔。

 缺點:SOAP協議內容需要自己封裝,使用soapUI工具之后也比較簡單。

     復雜對象需要解析XML,不過目前XML與對象映射的都很簡單,問題不大。

HttpClient調用WebService

1.通過WSDL,編寫SOAP協議

  (1)如果能看懂WSDL和SOAP,完全可以自己寫出來。當然也可以通過soapUI工具 實現

           熟悉WSDL文檔:http://www.360doc.com/content/16/1027/00/37651083_601648996.shtml

  (2)下載soapUI 4.5.2

 

 

 

 2.httpClient方法

/**
     * 使用SOAP1.1發送消息
     * 
     * @param postUrl
     * @param soapXml
     * @param soapAction
     * @return
     * @throws Exception 
     */
    public static String doPostSoap1_1(String postUrl, String soapXml,
                String soapAction, int socketTimeout,String serviceName) {
        String retStr = "";
        // 創建HttpClientBuilder
        HttpClientBuilder httpClientBuilder = HttpClientBuilder.create();
        // HttpClient
        CloseableHttpClient closeableHttpClient = httpClientBuilder.build();
        HttpPost httpPost = new HttpPost(postUrl);
                //  設置請求和傳輸超時時間
        //如果沒有傳送超時,默認兩分鍾
        if (socketTimeout <= 0){
            socketTimeout = HttpKit.socketTimeout;
        }
        RequestConfig requestConfig = RequestConfig.custom()
                .setSocketTimeout(socketTimeout)
                .setConnectTimeout(connectTimeout).build();
        httpPost.setConfig(requestConfig);
        try {
            httpPost.setHeader("Content-Type", "text/xml;charset=UTF-8");
            httpPost.setHeader("SOAPAction", soapAction);
            StringEntity data = new StringEntity(soapXml,
                    Charset.forName("UTF-8"));
            httpPost.setEntity(data);
            CloseableHttpResponse response = closeableHttpClient
                    .execute(httpPost);
            HttpEntity httpEntity = response.getEntity();
            if (httpEntity != null) {
                // 打印響應內容
                retStr = EntityUtils.toString(httpEntity, "UTF-8");
            }
            // 釋放資源
            closeableHttpClient.close();
        } catch (ConnectTimeoutException e) {
            logger.error("URL["+postUrl+"]"+serviceName+"連接超時:"+e.getMessage());
            throw e;
            
        } catch (SocketTimeoutException e) {
            logger.error("URL["+postUrl+"]"+serviceName+"響應超時:"+e.getMessage());
            throw e;
        } catch (Exception e) {
logger.error(
"URL["+postUrl+"]"+serviceName+"出現未知異常:"+e.getMessage(),e);
throw e;

}
return retStr;
}

/**
     * 使用SOAP1.2發送消息
     * 
     * @param postUrl
     * @param soapXml
     * @param soapAction
     * @return
     * @throws Exception 
     */
    public static String doPostSoap1_2(String postUrl, String soapXml,
            String soapAction, int socketTimeout) throws Exception {
        String retStr = "";
        // 創建HttpClientBuilder
        HttpClientBuilder httpClientBuilder = HttpClientBuilder.create();
        // HttpClient
        CloseableHttpClient closeableHttpClient = httpClientBuilder.build();
        HttpPost httpPost = new HttpPost(postUrl);
                // 設置請求和傳輸超時時間
        //如果沒有傳送超時,默認兩分鍾
        if (socketTimeout <= 0){
            socketTimeout = HttpKit.socketTimeout;
        }
        RequestConfig requestConfig = RequestConfig.custom()
                .setSocketTimeout(socketTimeout)
                .setConnectTimeout(connectTimeout).build();
        httpPost.setConfig(requestConfig);
        try {
            httpPost.setHeader("Content-Type",
                    "application/soap+xml;charset=UTF-8");
            httpPost.setHeader("SOAPAction", soapAction);
            StringEntity data = new StringEntity(soapXml,
                    Charset.forName("UTF-8"));
            httpPost.setEntity(data);
            CloseableHttpResponse response = closeableHttpClient
                    .execute(httpPost);
            HttpEntity httpEntity = response.getEntity();
            if (httpEntity != null) {
                // 打印響應內容
                retStr = EntityUtils.toString(httpEntity, "UTF-8");
            }
            // 釋放資源
            closeableHttpClient.close();
        } catch (ConnectTimeoutException e) { logger.error("URL["+postUrl+"]"+serviceName+"連接超時:"+e.getMessage()); throw e; } catch (SocketTimeoutException e) { logger.error("URL["+postUrl+"]"+serviceName+"響應超時:"+e.getMessage());
            throw e;
 
         
        } catch (Exception e) {
logger.error("URL["+postUrl+"]"+serviceName+"出現未知異常:"+e.getMessage(),e);
throw e;
}
return retStr; } 

3.傳送的soapXML參數

<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:web="http://webservice.xxx.xxx.xxx">
  <soapenv:Header/>
  <soapenv:Body>
      <web:queryUser>

                         <account>?</account>
                         <areaCode>?</areaCode>
                         <carNo>?</carNo>

           </web:queryUser>
  </soapenv:Body>
</soapenv:Envelope>

注意:如果傳送的參數是XML字符串,那么需要使用轉義或者使用<![CDATA[ "+xmlStr+"]]>,建議使用<![CDATA[ "+xmlStr+"]]>的方式。

 

 

 

 

 

 

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM