一、引入cxf3
我這裡使用的是最新的版本cxf3.1.8
引入cxf3需要在pom.xml加入如下內容:
<dependency> <groupId>org.apache.cxf</groupId> <artifactId>cxf-rt-frontend-jaxws</artifactId> <version>3.1.8</version> </dependency> <dependency> <groupId>org.apache.cxf</groupId> <artifactId>cxf-rt-transports-http</artifactId> <version>3.1.8</version> </dependency>
二、專案中增加對cxf3的支援
1、修改web.xml,增加如下內容不:
<!-- cxf webservices --> <servlet> <description>CXF Endpoint</description> <display-name>cxf</display-name> <servlet-name>cxf</servlet-name> <servlet-class>org.apache.cxf.transport.servlet.CXFServlet</servlet-class> <load-on-startup>2</load-on-startup> </servlet> <servlet-mapping> <servlet-name>cxf</servlet-name> <url-pattern>/services/*</url-pattern> </servlet-mapping>
2、新增spring的配置檔案application-cxf.xml,內容如下(web.xml中掃描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:jaxws="http://cxf.apache.org/jaxws" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://cxf.apache.org/jaxws http://cxf.apache.org/schemas/jaxws.xsd"> <import resource="classpath:META-INF/cxf/cxf.xml" /> <import resource="classpath:META-INF/cxf/cxf-servlet.xml" /> <!-- Cxf WebService 服務端示例 --> <jaxws:endpoint id="DemoWebservice" implementor="com.comp.web.webservice.impl.DemoWebserviceImpl" address="/demo"/> <!-- Cxf WebService 客戶端示例 --> <jaxws:client id="demoClient" serviceClass="com.comp.web.webservice.DemoWebservice" address="http://localhost:8080/App/services/demo?wsdl" /> </beans>
注意看上面有服務端以及客戶端的示例宣告,下面會給出編寫服務端及客戶端的具體程式碼
三、編寫服務端程式碼
1、application-cxf.xml檔案中新增宣告:
<!-- Cxf WebService 服務端示例 --> <jaxws:endpoint id="DemoWebservice" implementor="com.comp.web.webservice.impl.DemoWebserviceImpl" address="/demo"/>
2、介面檔案DemoWebservice.java,程式碼如下:
package com.huarui.web.webservice; import javax.jws.WebService; @WebService public interface DemoWebservice { public String queryBaseTx(); public String queryBaseTxById(String id); }
3、實現檔案DemoWebserviceImpl.java,程式碼如下:
package com.comp.web.webservice.impl; import java.util.List; import javax.jws.WebService; import org.springframework.beans.factory.annotation.Autowired; import com.google.gson.Gson; import com.comp.mapping.entity.BasetxEntity; import com.comp.service.jdbc.BasetxService; import com.comp.web.webservice.DemoWebservice; @WebService(endpointInterface = "com.comp.web.webservice.DemoWebservice") public class DemoWebserviceImpl implements DemoWebservice { @Autowired private BasetxService basetxService; public String queryBaseTx() { List list = basetxService.findAll(); return new Gson().toJson(list); } public String queryBaseTxById(String id) { BasetxEntity basetx = basetxService.findById(id); return new Gson().toJson(basetx); } }
重啟專案,用這個地址就可以訪問我們建立的服務列表了 http://localhost:8080/App/services/
對於我們剛才建立的服務的訪問地址為:http://localhost:8080/App/services/demo?wsdl
路徑中services對應的是web.xml檔案中配置的內容
demo?wsdl對應的是application-cxf.xml檔案中的address屬性
四、編寫客戶端程式碼
1、application-cxf.xml檔案中新增宣告:
<!-- Cxf WebService 客戶端示例 --> <jaxws:client id="demoClient" serviceClass="com.comp.web.webservice.DemoWebservice" address="http://localhost:8080/App/services/demo?wsdl" />
2、controller類中,新增如下程式碼:
@Autowired @Qualifier("demoClient") private DemoWebservice demo; ...... String result = demo.queryBaseTx(); System.out.println(result);
com.comp.web.webservice.DemoWebservice是基於服務端的介面實現,本來是要重新寫的,我這裡偷了個懶,直接用了服務端的程式碼
Qualifier註解裡面的demoClient對應的是application-cxf.xml配置裡面jaxws:client標籤的id屬性
com.comp.web.webservice.DemoWebservice是介面,沒有實現類,通過jaxws:client標籤呼叫服務地址生成實現類
五、編寫客戶端程式碼(第二種方式)
這種方式不需要配置application-cxf.xml檔案
在controller類中,新增如下程式碼:
URL wsdlURL = new URL("http://localhost:8080/App/services/demo?wsdl"); QName SERVICE_NAME = new QName("http://impl.webservice.web.comp.com/", "DemoWebserviceImplService"); Service service = Service.create(wsdlURL, SERVICE_NAME); DemoWebservice client = service.getPort(DemoWebservice.class); String result = client.queryBaseTx(); System.out.println(result);
我建議使用第一種方式,第二種方式這個QName需要從服務端介面裡去找,然後我想說的是,QName並不太好找,寫錯了程式碼執行會報錯。
我這裡把我生成的服務端wsdl的內容貼出來:
<wsdl:definitions xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/" xmlns:tns="http://impl.webservice.web.huarui.com/"
xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/" xmlns:ns2="http://schemas.xmlsoap.org/soap/http" xmlns:ns1="http://webservice.web.huarui.com/"
name="DemoWebserviceImplService" targetNamespace="http://impl.webservice.web.comp.com/"> <wsdl:import location="http://localhost:8080/App/services/demo?wsdl=DemoWebservice.wsdl" namespace="http://webservice.web.comp.com/"></wsdl:import> <wsdl:binding name="DemoWebserviceImplServiceSoapBinding" type="ns1:DemoWebservice"> <soap:binding style="document" transport="http://schemas.xmlsoap.org/soap/http"/> <wsdl:operation name="queryBaseTx"> <soap:operation soapAction="" style="document"/> <wsdl:input name="queryBaseTx"> <soap:body use="literal"/> </wsdl:input> <wsdl:output name="queryBaseTxResponse"> <soap:body use="literal"/> </wsdl:output> </wsdl:operation> <wsdl:operation name="queryBaseTxById"> <soap:operation soapAction="" style="document"/> <wsdl:input name="queryBaseTxById"> <soap:body use="literal"/> </wsdl:input> <wsdl:output name="queryBaseTxByIdResponse"> <soap:body use="literal"/> </wsdl:output> </wsdl:operation> </wsdl:binding> <wsdl:service name="DemoWebserviceImplService"> <wsdl:port binding="tns:DemoWebserviceImplServiceSoapBinding" name="DemoWebserviceImplPort"> <soap:address location="http://localhost:8080/App/services/demo"/> </wsdl:port> </wsdl:service> </wsdl:definitions>
注意看一下,這個QName裡面的引數對應的是wsdl:definitions標籤裡面的targetNamespace屬性和name屬性
六、編寫客戶端程式碼(第三種方式)
使用cxf工具裡面的wsdl2java生成客戶端程式碼,我參考的這篇文章:http://blog.csdn.net/hu_shengyang/article/details/38384839
我這裡不再介紹這種方法
我生成客戶端程式碼的命令是:
wsdl2java -p com.comp.web.client -d d:\web\client -client http://localhost:8080/App/services/demo?wsdl