因爲公司業務需求, 須要使用WebService技術對外提供服務,之前沒有作過相似的項目,在網上搜尋了不少資料,最終決定使用Cxf + Spring的框架,緣由很簡單,就是由於Cxf功能強大而且能夠和Spring無縫集成。java
Apache CXF 是一個開放源代碼框架,提供了用於方便地構建和開發 Web 服務的可靠基礎架構。它容許建立高性能和可擴展的服務,您能夠將這樣的服務部署在 Tomcat 和基於 Spring 的輕量級容器中,以及部署在更高級的服務器上,例如 Jboss、IBM® WebSphere® 或 BEA WebLogic。web
首先說明一下項目中使用的jar包以下圖,服務器端項目項目名稱 CxfSpringServer, 客戶端項目名稱爲 CxfSpringClient 兩個項目使用的都是如下的jar包, 程序中沒有使用最新的cxf-2.4.1版本由於, 該版本不知道是否有問題, 啓動的時候老是報錯。Spring使用的是3.0。spring
第一部分開發服務器端: sql
1: 開發接口程序,接口中定義了serviceName的名稱,以及命名空間,注意這個命名空間就是未來客戶端中生成的接口的package的路徑。apache
另外@WebResult(name="out") 這句話定義了wadl文件中輸出數據的名字,cxf中默認的輸出名稱是tomcat
return,當時要改這個名字也花了很多時間。須要改動這個名稱的朋友請注意這個細節。服務器
- package com.cxf.bo;
- import javax.jws.WebParam;
- import javax.jws.WebResult;
- import javax.jws.WebService;
- @WebService(serviceName="IWsTestBO",targetNamespace="http://impl.ws.com")
- public interface IWsTestBO {
- @WebResult(name="out")
- public String execute(@WebParam(name = "arg0",targetNamespace="http://impl.ws.com")String arg0);
- }
2: 接下來開發IWsTestBO 接口的實現類。架構
@Service("wsServiceBO") 採用的是spring3.0的註解開發。app
- package com.cxf.bo.impl;
- import javax.jws.WebService;
- import org.springframework.stereotype.Service;
- import com.cxf.bo.IWsTestBO;
- @Service("wsServiceBO")
- @WebService(targetNamespace="http://impl.ws.com")
- public class WsTestBOImpl implements IWsTestBO{
- public String execute(String arg0) {
- return "歡迎 " + arg0 + ",調用WebService服務....";
- }
- }
3: Spring的配置文件 bo-context.xml。配置文件中定義了WebService的相關屬性,注意配置文件中的命名空間的定義是必不可少的。jaxws:endpointbiaoq標籤訂義了提供Web服務的 Bean 訪問地址。 而且配置了服務器接受數據的日誌配置,當服務器接受到訪問數據時jaxws:features標籤配置能夠將最原始的日誌打印到控制檯上。框架
- <?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:xsd="http://www.w3.org/2001/XMLSchema"
- xmlns:context="http://www.springframework.org/schema/context"
- xmlns:jaxws="http://cxf.apache.org/jaxws"
- xsi:schemaLocation="http://www.springframework.org/schema/beans
- http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
- http://www.springframework.org/schema/context
- http://www.springframework.org/schema/context/spring-context-3.0.xsd
- http://cxf.apache.org/jaxws
- http://cxf.apache.org/schemas/jaxws.xsd">
- <context:component-scan base-package="com.cxf.bo"/>
- <import resource="classpath:META-INF/cxf/cxf.xml"/>
- <import resource="classpath:META-INF/cxf/cxf-extension-soap.xml"/>
- <import resource="classpath:META-INF/cxf/cxf-servlet.xml"/>
- <jaxws:endpoint id="wsServiceBean" implementor="#wsServiceBO" address="/execute" publish="true" >
- <jaxws:features>
- <bean class="org.apache.cxf.feature.LoggingFeature" />
- </jaxws:features>
- </jaxws:endpoint>
- </beans>
4:接下來是web.xml文件的配置:
- <?xml version="1.0" encoding="UTF-8"?>
- <web-app version="2.5"
- xmlns="http://java.sun.com/xml/ns/javaee"
- xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
- xsi:schemaLocation="http://java.sun.com/xml/ns/javaee
- http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd">
- <context-param>
- <param-name>contextConfigLocation</param-name>
- <param-value>/WEB-INF/bo-context.xml</param-value>
- </context-param>
- <listener>
- <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
- </listener>
- <servlet>
- <servlet-name>CXFServlet</servlet-name>
- <servlet-class>org.apache.cxf.transport.servlet.CXFServlet</servlet-class>
- <load-on-startup>0</load-on-startup>
- </servlet>
- <servlet-mapping>
- <servlet-name>CXFServlet</servlet-name>
- <url-pattern>/services/*</url-pattern>
- </servlet-mapping>
- </web-app>
5: 到如今爲止服務器端的程序已經開發完成,是否是很簡單。如今能夠部署到Tomcat6.0服務器。在部署服務器的時候還有一個須要注意的問題。部署tomcat沒有問題,可是部署到resin服務器的時候就會報異常: property "javax.xml.stream.supportDTD" not supported 。上網查詢了一些資料,發現的確是resin服務器有問題, 改進方案是, 首先在resin.conf配置中找到以下代碼:
- <!-- Uncomment to use Resin's XML implementations
- - <system-property javax.xml.parsers.DocumentBuilderFactory
- - ="com.caucho.xml.parsers.XmlDocumentBuilderFactory"/>
- - <system-property javax.xml.parsers.SAXParserFactory
- - ="com.caucho.xml.parsers.XmlSAXParserFactory"/>
- -->
若是已經使用,就替換下面,若是沒有使用,就加上下面的配置
- <system-property javax.xml.stream.XMLInputFactory="com.sun.xml.internal.stream.XMLInputFactoryImpl" />
部署以後訪問以下地址 http://localhost:9113/CxfSpringServer/services/execute?wsdl 我電腦用的是9113的端口,你的確定和個人是不同的,因此你訪問的時候改一下端口就能夠了。地址訪問成功時候會出現一個xml的配置文件的信息,這裏就不展現了。
第二部分開發客戶端:
1: 客戶端和服務器端是兩個獨立的應用,jar包用的是同一組。若是你用myeclipse的話能夠經過myeclipse自帶的webservice客戶端生成嚮導生成客戶端接口。根據地址生成客戶端這樣比較方便,可是生成的文件中除了接口類以外,其它都沒什麼用的,能夠刪掉。
2: 客戶端接口類以下
- package com.ws.impl;
- import javax.jws.WebMethod;
- import javax.jws.WebParam;
- import javax.jws.WebResult;
- import javax.jws.WebService;
- import javax.xml.ws.RequestWrapper;
- import javax.xml.ws.ResponseWrapper;
- @WebService(name = "IWsTestBO", targetNamespace = "http://impl.ws.com")
- public interface IWsTestBO {
- @WebMethod
- @WebResult(name = "out", targetNamespace = "")
- @RequestWrapper(localName = "execute", targetNamespace = "http://impl.ws.com", className = "com.ws.impl.Execute")
- @ResponseWrapper(localName = "executeResponse", targetNamespace = "http://impl.ws.com", className = "com.ws.impl.ExecuteResponse")
- public String execute(@WebParam(name = "arg0", targetNamespace = "http://impl.ws.com") String arg0);
- }
3: 客戶端的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:xsd="http://www.w3.org/2001/XMLSchema"
- xmlns:context="http://www.springframework.org/schema/context"
- xmlns:jaxws="http://cxf.apache.org/jaxws"
- xsi:schemaLocation="http://www.springframework.org/schema/beans
- http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
- http://www.springframework.org/schema/context
- http://www.springframework.org/schema/context/spring-context-3.0.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-extension-soap.xml"/>
- <import resource="classpath:META-INF/cxf/cxf-servlet.xml"/>
- <bean id="wsClient" class="com.ws.impl.IWsTestBO" factory-bean="clientFactory" factory-method="create"/>
- <bean id="clientFactory" class="org.apache.cxf.jaxws.JaxWsProxyFactoryBean">
- <property name="serviceClass" value="com.ws.impl.IWsTestBO"/>
- <property name="address" value="http://localhost:9113/CxfSpringServer/services/execute?wsdl"/>
- </bean>
- </beans>
4: 客戶端主函數測試類以下:
- package com.test;
- import org.springframework.context.ApplicationContext;
- import org.springframework.context.support.ClassPathXmlApplicationContext;
- import com.ws.impl.IWsTestBO;
- public class WsTestClient {
- public static void main(String[] args) {
- ApplicationContext ctx = new ClassPathXmlApplicationContext(new String[]{"bo-context.xml"});
- IWsTestBO client = (IWsTestBO)ctx.getBean("wsClient");
- String result = client.execute("張健");
- System.out.println(result);
- }
- }
5:服務器端輸入輸出日誌以下:
- 信息: Inbound Message
- ----------------------------
- ID: 1
- Address: /CxfSpringServer/services/execute
- Encoding: UTF-8
- Content-Type: text/xml; charset=UTF-8
- Headers: {cache-control=[no-cache], content-type=[text/xml; charset=UTF-8], connection=[keep-alive], host=[localhost:9113], Content-Length=[213], SOAPAction=[""], user-agent=[Apache CXF 2.2.12], Content-Type=[text/xml; charset=UTF-8], Accept=[*/*], pragma=[no-cache]}
- Payload: <soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/"><soap:Body><ns1:execute xmlns:ns1="http://impl.ws.com"><arg0 xmlns="http://impl.ws.com">張健</arg0></ns1:execute></soap:Body></soap:Envelope>
- --------------------------------------
- 2011-7-29 12:59:07 org.apache.cxf.interceptor.LoggingOutInterceptor$LoggingCallback onClose
- 信息: Outbound Message
- ---------------------------
- ID: 1
- Encoding: UTF-8
- Content-Type: text/xml
- Headers: {}
- Payload: <soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/"><soap:Body><ns1:executeResponse xmlns:ns1="http://impl.ws.com"><out>歡迎 張健,調用WebService服務....</out></ns1:executeResponse></soap:Body></soap:Envelope>
- --------------------------------------
關於Cxf + Spring3.0 集成開發WebService服務的入門例子程序就寫到這裏,有問題的童鞋能夠留言。咱們一塊兒討論, 謝謝!