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