使用Apache CXF框架開發webservice服務的客戶端
場景: webservice服務的客戶端用來訪問webservice這是個異構的架構,
本客戶端使用Java開發,服務端不限程式語言,只需遵循wsdl規範即可。
1.在開發客戶端時,會得到需要訪問的服務的釋出服務地址,本例使用如下地址:
http://127.0.0.1:8080/study/ws/publicService?wsdl
本例的服務端可參考: 服務端實現
2.在瀏覽器中訪問 http://127.0.0.1:8080/study/ws/publicService?wsdl
可以得到wsdl文件資訊,說明對方服務正常且可用,開發客戶端需要從中獲取相關資訊
<1>.服務方釋出了什麼方法,方法的入參型別,方法返回型別,入參個數,從文件可以找到:
本例方法是:getCityInfo
入參型別: string
<xs:element minOccurs="0" name="arg0" type="xs:string"/>
返回型別: string
<xs:element minOccurs="0" name="return" type="xs:string"/>
<2>.服務的名稱空間
http://webservice.zbz.com/
3.程式碼如下:
package com.zbz.client; import java.text.SimpleDateFormat; import java.util.Date; import javax.xml.namespace.QName; import org.apache.cxf.endpoint.Client; import org.apache.cxf.jaxws.endpoint.dynamic.JaxWsDynamicClientFactory; import org.apache.cxf.transport.http.HTTPConduit; import org.apache.cxf.transports.http.configuration.HTTPClientPolicy; /** * CxfClient可以訪問服務端釋出的webservice服務 * @ClassName: CxfClient * @date: 2018-12-30 下午12:53:32 */ public class CxfClient { /**釋出服務方釋出的地址*/ final static String wsdlUrl = "http://127.0.0.1:8080/study/ws/publicService?wsdl"; final static String targetNamespace = "http://webservice.zbz.com/"; final static long receiveTimeout = 1000 * 90; // 90秒 cxf 預設是60秒 final static long connectionTimeout = 1000 * 30; // 30秒 /**本客戶端呼叫CXF服務*/ public static void invokeCxf(String method, Object... args) { JaxWsDynamicClientFactory factory = JaxWsDynamicClientFactory.newInstance(); QName service = new QName(targetNamespace, "PublicInterfaceService"); QName namePort = new QName(targetNamespace, "PublicInterfacePort"); Client client = factory.createClient(wsdlUrl, service, namePort); // 獲取HttpClient代理,並設定代理的埠號,超時時間等。 HTTPClientPolicy httpClientPolicy = new HTTPClientPolicy(); // 設定超時 HTTPConduit confuit = (HTTPConduit) client.getConduit(); // 設定連線超時 httpClientPolicy.setConnectionTimeout(connectionTimeout); // 設定讀取超時 httpClientPolicy.setReceiveTimeout(receiveTimeout); confuit.setClient(httpClientPolicy); Object[] result; System.out.println(getCurrentTime() +" : "+ "CXF客戶端開始呼叫服務....."); try { result = client.invoke(method, args); System.out.println(result[0]); System.out.println(getCurrentTime() +" : "+ "CXF客戶端結束呼叫服務....."); } catch (Exception e) { e.printStackTrace(); } } public static void main(String []args){ System.out.println(getCurrentTime() +" : 開始測試...."); String method = "getCityInfo"; String arg0 ="廈門"; invokeCxf(method,arg0); System.out.println(getCurrentTime() +" : 結束測試...."); } /**提供格式化時間2018-10-10*/ public static String getCurrentTime() { Date now = new Date(); SimpleDateFormat ft = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); System.currentTimeMillis(); return ft.format(now); } }
解析: <1>.invokeCxf(String method, Object... args)簡單封裝,把CXF相關呼叫封裝在這裡
<2>.程式碼解析
QName service = new QName(targetNamespace, "PublicInterfaceService");
QName namePort = new QName(targetNamespace, "PublicInterfacePort");
這兩行程式碼中:PublicInterfaceService和PublicInterfacePort來wsdl文件中
<wsdl:service name="PublicInterfaceService">
<wsdl:port binding="tns:PublicInterfaceServiceSoapBinding" name="PublicInterfacePort">
<soap:address location="http://127.0.0.1:8080/study/ws/publicService"/>
</wsdl:port>
</wsdl:service>
<3>.targetNamespace定義的一個字串屬性,值是來自wsdl文件中的名稱空間
"http://webservice.zbz.com/"
4.如下完整的wsdl文件資訊
This XML file does not appear to have any style information associated with it. The document tree is shown below.
<wsdl:definitions xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/" xmlns:tns="http://webservice.zbz.com/" xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/" xmlns:ns1="http://schemas.xmlsoap.org/soap/http" name="PublicInterfaceService" targetNamespace="http://webservice.zbz.com/">
<wsdl:types>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:tns="http://webservice.zbz.com/" elementFormDefault="unqualified" targetNamespace="http://webservice.zbz.com/" version="1.0">
<xs:element name="getCityInfo" type="tns:getCityInfo"/>
<xs:element name="getCityInfoResponse" type="tns:getCityInfoResponse"/>
<xs:complexType name="getCityInfo">
<xs:sequence>
<xs:element minOccurs="0" name="arg0" type="xs:string"/>
</xs:sequence>
</xs:complexType>
<xs:complexType name="getCityInfoResponse">
<xs:sequence>
<xs:element minOccurs="0" name="return" type="xs:string"/>
</xs:sequence>
</xs:complexType>
</xs:schema>
</wsdl:types>
<wsdl:message name="getCityInfoResponse">
<wsdl:part element="tns:getCityInfoResponse" name="parameters"></wsdl:part>
</wsdl:message>
<wsdl:message name="getCityInfo">
<wsdl:part element="tns:getCityInfo" name="parameters"></wsdl:part>
</wsdl:message>
<wsdl:portType name="PublicInterface">
<wsdl:operation name="getCityInfo">
<wsdl:input message="tns:getCityInfo" name="getCityInfo"></wsdl:input>
<wsdl:output message="tns:getCityInfoResponse" name="getCityInfoResponse"></wsdl:output>
</wsdl:operation>
</wsdl:portType>
<wsdl:binding name="PublicInterfaceServiceSoapBinding" type="tns:PublicInterface">
<soap:binding style="document" transport="http://schemas.xmlsoap.org/soap/http"/>
<wsdl:operation name="getCityInfo">
<soap:operation soapAction="" style="document"/>
<wsdl:input name="getCityInfo">
<soap:body use="literal"/>
</wsdl:input>
<wsdl:output name="getCityInfoResponse">
<soap:body use="literal"/>
</wsdl:output>
</wsdl:operation>
</wsdl:binding>
<wsdl:service name="PublicInterfaceService">
<wsdl:port binding="tns:PublicInterfaceServiceSoapBinding" name="PublicInterfacePort">
<soap:address location="http://127.0.0.1:8080/study/ws/publicService"/>
</wsdl:port>
</wsdl:service>
</wsdl:definitions>
以上,TKS.