转自:https://blog.csdn.net/zilong_zilong/article/details/53932667
httpclient妙用一 httpclient作为客户端调用webservice | http://aperise.iteye.com/blog/2223454 |
httpclient妙用二 httpclient保持会话登录 | http://aperise.iteye.com/blog/2223470 |
httpclient连接池 | http://aperise.iteye.com/blog/2295153 |
httpclient作为客户端调用webservice
1.个人观点
webservice框架有很多,比如axis、axis2、cxf、xFire等等,做服务端和做客户端都可行,个人感觉使用这些框架的好处是减少了对于接口信息的解析,最主要的是减少了对于传递于网络中XML的解析,代价是你不得不在你的框架中添加对于这些框架的依赖。个人观点是:服务端使用这些框架还行,如果做客户端,没必要使用这些框架,只需使用httpclient即可。
2.需求场景
已经拿到对于接口的描述文件WebServiceFromB.wsdl,需要建立客户端进行调用,WebServiceFromB.wsdl内容如下:
- <?xml version="1.0" encoding="UTF-8"?>
- <wsdl:definitions targetNamespace="http://webservices.b.com" xmlns:apachesoap="http://xml.apache.org/xml-soap" xmlns:impl="http://webservices.b.com" xmlns:intf="http://webservices.b.com" xmlns:soapenc="http://schemas.xmlsoap.org/soap/encoding/" xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/" xmlns:wsdlsoap="http://schemas.xmlsoap.org/wsdl/soap/" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
- <!--WSDL created by Apache Axis version: 1.4
- Built on Apr 22, 2006 (06:55:48 PDT)-->
- <wsdl:types>
- <schema targetNamespace="http://webservices.b.com" xmlns="http://www.w3.org/2001/XMLSchema">
- <import namespace="http://schemas.xmlsoap.org/soap/encoding/"/>
- <complexType name="OrderRequest">
- <sequence>
- <element name="mobile" nillable="true" type="soapenc:string"/>
- <element name="orderStatus" type="xsd:int"/>
- <element name="productCode" nillable="true" type="soapenc:string"/>
- </sequence>
- </complexType>
- <complexType name="OrderResponse">
- <sequence>
- <element name="status" type="xsd:int"/>
- </sequence>
- </complexType>
- <complexType name="QueryRequest">
- <sequence>
- <element name="endTime" nillable="true" type="xsd:dateTime"/>
- <element name="mobile" nillable="true" type="soapenc:string"/>
- <element name="startTime" nillable="true" type="xsd:dateTime"/>
- </sequence>
- </complexType>
- <complexType name="QueryResponse">
- <sequence>
- <element name="product" nillable="true" type="soapenc:string"/>
- <element name="status" type="xsd:int"/>
- </sequence>
- </complexType>
- </schema>
- </wsdl:types>
- <wsdl:message name="queryRequest">
- <wsdl:part name="in0" type="impl:QueryRequest"/>
- </wsdl:message>
- <wsdl:message name="orderResponse">
- <wsdl:part name="orderReturn" type="impl:OrderResponse"/>
- </wsdl:message>
- <wsdl:message name="queryResponse">
- <wsdl:part name="queryReturn" type="impl:QueryResponse"/>
- </wsdl:message>
- <wsdl:message name="orderRequest">
- <wsdl:part name="in0" type="impl:OrderRequest"/>
- </wsdl:message>
- <wsdl:portType name="WebServiceFromB">
- <wsdl:operation name="order" parameterOrder="in0">
- <wsdl:input message="impl:orderRequest" name="orderRequest"/>
- <wsdl:output message="impl:orderResponse" name="orderResponse"/>
- </wsdl:operation>
- <wsdl:operation name="query" parameterOrder="in0">
- <wsdl:input message="impl:queryRequest" name="queryRequest"/>
- <wsdl:output message="impl:queryResponse" name="queryResponse"/>
- </wsdl:operation>
- </wsdl:portType>
- <wsdl:binding name="WebServiceFromBSoapBinding" type="impl:WebServiceFromB">
- <wsdlsoap:binding style="rpc" transport="http://schemas.xmlsoap.org/soap/http"/>
- <wsdl:operation name="order">
- <wsdlsoap:operation soapAction=""/>
- <wsdl:input name="orderRequest">
- <wsdlsoap:body encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" namespace="http://webservices.b.com" use="encoded"/>
- </wsdl:input>
- <wsdl:output name="orderResponse">
- <wsdlsoap:body encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" namespace="http://webservices.b.com" use="encoded"/>
- </wsdl:output>
- </wsdl:operation>
- <wsdl:operation name="query">
- <wsdlsoap:operation soapAction=""/>
- <wsdl:input name="queryRequest">
- <wsdlsoap:body encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" namespace="http://webservices.b.com" use="encoded"/>
- </wsdl:input>
- <wsdl:output name="queryResponse">
- <wsdlsoap:body encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" namespace="http://webservices.b.com" use="encoded"/>
- </wsdl:output>
- </wsdl:operation>
- </wsdl:binding>
- <wsdl:service name="WebServiceFromBService">
- <wsdl:port binding="impl:WebServiceFromBSoapBinding" name="WebServiceFromB">
- <wsdlsoap:address location="http://localhost:8080/services/WebServiceFromB"/>
- </wsdl:port>
- </wsdl:service>
- </wsdl:definitions>
3.获取调用报文
1.首先得安装soapUI 4.5.2,安装后打开,截图如下:
2.右键点击“Projects”创建工程,截图如下:
3.双击展开左侧创建的工程下所有节点,最后双击“Request 1”节点,在右侧即可拿到soap格式消息,这个就是我们后面作为客户端调用服务端的报文内容,截图如下:
拿到的调用order的soap消息为:
- <soapenv:Envelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:web="http://webservices.b.com">
- <soapenv:Header/>
- <soapenv:Body>
- <web:order soapenv:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/">
- <in0 xsi:type="web:OrderRequest">
- <mobile xsi:type="soapenc:string" xmlns:soapenc="http://schemas.xmlsoap.org/soap/encoding/">?</mobile>
- <orderStatus xsi:type="xsd:int">?</orderStatus>
- <productCode xsi:type="soapenc:string" xmlns:soapenc="http://schemas.xmlsoap.org/soap/encoding/">?</productCode>
- </in0>
- </web:order>
- </soapenv:Body>
- </soapenv:Envelope>
拿到的调用query的soap消息为:
- <soapenv:Envelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:web="http://webservices.b.com">
- <soapenv:Header/>
- <soapenv:Body>
- <web:query soapenv:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/">
- <in0 xsi:type="web:QueryRequest">
- <endTime xsi:type="xsd:dateTime">?</endTime>
- <mobile xsi:type="soapenc:string" xmlns:soapenc="http://schemas.xmlsoap.org/soap/encoding/">?</mobile>
- <startTime xsi:type="xsd:dateTime">?</startTime>
- </in0>
- </web:query>
- </soapenv:Body>
- </soapenv:Envelope>
4.用httpclient发送soap消息
-
<dependency>
-
<groupId>org.apache.httpcomponents </groupId>
-
<artifactId>httpclient </artifactId>
-
<version>4.3.2 </version>
-
</dependency>
-
<dependency>
-
<groupId>org.apache.httpcomponents </groupId>
-
<artifactId>fluent-hc </artifactId>
-
<version>4.3.2 </version>
-
</dependency>
-
<dependency>
-
<groupId>org.apache.httpcomponents </groupId>
-
<artifactId>http-core </artifactId>
-
<version>4.3.2 </version>
-
</dependency>
直接上代码,代码如下:
-
import java.nio.charset.Charset;
-
import org.apache.http.HttpEntity;
-
import org.apache.http.client.config.RequestConfig;
-
import org.apache.http.client.methods.CloseableHttpResponse;
-
import org.apache.http.client.methods.HttpPost;
-
import org.apache.http.entity.StringEntity;
-
import org.apache.http.impl.client.CloseableHttpClient;
-
import org.apache.http.impl.client.HttpClientBuilder;
-
import org.apache.http.util.EntityUtils;
-
import org.apache.log4j.Logger;
-
-
public class HttpClientCallSoapUtil {
-
static int socketTimeout = 30000; // 请求超时时间
-
static int connectTimeout = 30000; // 传输超时时间
-
static Logger logger = Logger.getLogger(HttpClientCallSoapUtil.class);
-
-
/**
-
* 使用SOAP1.1发送消息
-
*
-
* @param postUrl
-
* @param soapXml
-
* @param soapAction
-
* @return
-
*/
-
public static String doPostSoap1_1(String postUrl, String soapXml,
-
String soapAction) {
-
String retStr = "";
-
// 创建HttpClientBuilder
-
HttpClientBuilder httpClientBuilder = HttpClientBuilder.create();
-
// HttpClient
-
CloseableHttpClient closeableHttpClient = httpClientBuilder.build();
-
HttpPost httpPost = new HttpPost(postUrl);
-
// 设置请求和传输超时时间
-
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");
-
logger.info( "response:" + retStr);
-
}
-
// 释放资源
-
closeableHttpClient.close();
-
} catch (Exception e) {
-
logger.error( "exception in doPostSoap1_1", e);
-
}
-
return retStr;
-
}
-
-
/**
-
* 使用SOAP1.2发送消息
-
*
-
* @param postUrl
-
* @param soapXml
-
* @param soapAction
-
* @return
-
*/
-
public static String doPostSoap1_2(String postUrl, String soapXml,
-
String soapAction) {
-
String retStr = "";
-
// 创建HttpClientBuilder
-
HttpClientBuilder httpClientBuilder = HttpClientBuilder.create();
-
// HttpClient
-
CloseableHttpClient closeableHttpClient = httpClientBuilder.build();
-
HttpPost httpPost = new HttpPost(postUrl);
-
// 设置请求和传输超时时间
-
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");
-
logger.info( "response:" + retStr);
-
}
-
// 释放资源
-
closeableHttpClient.close();
-
} catch (Exception e) {
-
logger.error( "exception in doPostSoap1_2", e);
-
}
-
return retStr;
-
}
-
-
public static void main(String[] args) {
-
String orderSoapXml = "<?xml version = \"1.0\" ?>"
-
+ "<soapenv:Envelope xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\" xmlns:soapenv=\"http://schemas.xmlsoap.org/soap/envelope/\" xmlns:web=\"http://webservices.b.com\">"
-
+ " <soapenv:Header/>"
-
+ " <soapenv:Body>"
-
+ " <web:order soapenv:encodingStyle=\"http://schemas.xmlsoap.org/soap/encoding/\">"
-
+ " <in0 xsi:type=\"web:OrderRequest\">"
-
+ " <mobile xsi:type=\"soapenc:string\" xmlns:soapenc=\"http://schemas.xmlsoap.org/soap/encoding/\">?</mobile>"
-
+ " <orderStatus xsi:type=\"xsd:int\">?</orderStatus>"
-
+ " <productCode xsi:type=\"soapenc:string\" xmlns:soapenc=\"http://schemas.xmlsoap.org/soap/encoding/\">?</productCode>"
-
+ " </in0>" + " </web:order>"
-
+ " </soapenv:Body>" + "</soapenv:Envelope>";
-
String querySoapXml = "<?xml version = \"1.0\" ?>"
-
+ "<soapenv:Envelope xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\" xmlns:soapenv=\"http://schemas.xmlsoap.org/soap/envelope/\" xmlns:web=\"http://webservices.b.com\">"
-
+ " <soapenv:Header/>"
-
+ " <soapenv:Body>"
-
+ " <web:query soapenv:encodingStyle=\"http://schemas.xmlsoap.org/soap/encoding/\">"
-
+ " <in0 xsi:type=\"web:QueryRequest\">"
-
+ " <endTime xsi:type=\"xsd:dateTime\">?</endTime>"
-
+ " <mobile xsi:type=\"soapenc:string\" xmlns:soapenc=\"http://schemas.xmlsoap.org/soap/encoding/\">?</mobile>"
-
+ " <startTime xsi:type=\"xsd:dateTime\">?</startTime>"
-
+ " </in0>" + " </web:query>"
-
+ " </soapenv:Body>" + "</soapenv:Envelope>";
-
String postUrl = "http://localhost:8080/services/WebServiceFromB";
-
//采用SOAP1.1调用服务端,这种方式能调用服务端为soap1.1和soap1.2的服务
-
doPostSoap1_1(postUrl, orderSoapXml, "");
-
doPostSoap1_1(postUrl, querySoapXml, "");
-
-
//采用SOAP1.2调用服务端,这种方式只能调用服务端为soap1.2的服务
-
//doPostSoap1_2(postUrl, orderSoapXml, "order");
-
//doPostSoap1_2(postUrl, querySoapXml, "query");
-
}
-
}
5.总结
优点:
1.使用httpclient作为客户端调用webservice,不用关注繁琐的webservice框架,只需找到SOAP消息格式,添加httpclient依赖就行。
2.使用httpclient调用webservice,建议采用soap1.1方式调用,经测试使用soap1.1方式能调用soap1.1和soap1.2的服务端。
缺点:
唯一的缺点是,你得自己解析返回的XML,找到你关注的信息内容。