在使用WebService時,我們通常都會在客戶端中設置請求超時的限制,以避免長時間的去連接不可用的服務器。在CXF的環境下,客戶端可通過兩個屬性配置超時限制:
- ConnectionTimeout - WebService以TCP連接為基礎,這個屬性可以理解為TCP握手時的時間設置,超過設置的時間就認為是連接超時.以毫秒為單位,默認是30000毫秒,即30秒。
- ReceiveTimeout - 這個屬性是發送WebService的請求后等待響應的時間,超過設置的時長就認為是響應超時.以毫秒為單位,默認是60000毫秒,即60秒.
這里可通過兩種方式對客戶端進行配置:
一、在spring的配置文件中進行設置。
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:jee="http://www.springframework.org/schema/jee"
xmlns:jaxws="http://cxf.apache.org/jaxws"
xmlns:http-conf="http://cxf.apache.org/transports/http/configuration"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-2.0.xsd
http://www.springframework.org/schema/jee
http://www.springframework.org/schema/jee/spring-jee-2.0.xsd
http://cxf.apache.org/jaxws http://cxf.apache.org/schemas/jaxws.xsd
http://cxf.apache.org/transports/http/configuration
http://cxf.apache.org/schemas/configuration/http-conf.xsd ">
<http-conf:conduit name="{WSDL Namespace}portName.http-conduit">
<http-conf:client ConnectionTimeout="10000" ReceiveTimeout="20000"/>
</http-conf:conduit>
</beans>
這里需要注意的有幾個地方:
1、需要指定http-conf名稱空間:xmlns:http-conf=http://cxf.apache.org/transports/http/configuration。
2、指定模式位置: http://cxf.apache.org/transports/http/configuration http://cxf.apache.org/schemas/configuration/http-conf.xsd。
3、http-conf:conduit中的name屬性,指定設置生效的服務。name屬性由service的namespace、WSDL中的port name和".http-conduit"組成,如{http://apache.org/hello_world}HelloWorld.http-conduit。如果將name屬性設置為“*.http-conduit”,則會對所有服務生效。
二、通過java代碼進行設置。
Client client = ClientProxy.getClient(port);
HTTPConduit http = (HTTPConduit) client.getConduit();
HTTPClientPolicy httpClientPolicy = new HTTPClientPolicy();
httpClientPolicy.setConnectionTimeout(36000);
httpClientPolicy.setAllowChunking(false);
httpClientPolicy.setReceiveTimeout(32000);
http.setClient(httpClientPolicy);
另外,WSDL中的endpoint的地址不一定是有效的,為避免客戶端請求使用該地址,我們在請求前應通過以下方式強行設置為可用的服務地址。
((BindingProvider) port).getRequestContext().put(BindingProvider.ENDPOINT_ADDRESS_PROPERTY,serviceUrl);