1. 程式人生 > >使用Apache CXF框架開發webservice服務的客戶端

使用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.