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+"]]>的方式。