CXF是apache旗下的開源框架,由Celtix + XFire這兩門經典的框架合成,是一套很是流行的web service框架。html
它提供了JAX-WS的全面支持,而且能夠根據實際項目的須要,採用代碼優先(Code First)或者 WSDL 優先(WSDL First)來輕鬆地實現 Web Services 的發佈和使用,同時它能與spring進行完美結合。java
在apache cxf官網提供了cxf較全面的幫助文檔,英語教好的童鞋能夠到這個地址學習:http://cxf.apache.org/docs/index.htmlweb
下面就以官網教程爲例,簡單介紹下cxf的使用。spring
一、依賴的jar包apache
去官網下載cxf壓縮文件:http://cxf.apache.org/download.html服務器
解壓後,把apache-cxf-2.4.1\lib目錄下的jar包引用到java項目中app
二、JAX-WS簡單實例框架
首先編寫一個ws接口:less
@WebService public interface HelloService { public String sayHi(String text); public String getUser(User user); public List<User> getListUser(); }
須要在接口頭部註明一個"WebService"註解,表示這是一個webservice。ide
至於User類則是一個序列化的javabean(在對象傳輸過程建議儘可能序列化,熟悉java io的朋友應該清楚這點):
public class User implements Serializable{ private static final long serialVersionUID = 1001881900957402607L; private Integer id; private String name; getter,setter... }
而後編寫接口的實現類:
@WebService(endpointInterface = "com.bless.ws.HelloService", serviceName = "HelloService",portName="HelloServicePort") public class HelloServiceImpl implements HelloService { @Override public String sayHi(String text) { System.out.println("sayHi called..."); return "Hi :" + text; } @Override public String getUser(User user) { System.out.println("sayUser called..."); return "User:[id=" + user.getId() + "][name=" + user.getName() + "]"; } @Override public List<User> getListUser() { System.out.println("getListUser called..."); List<User> lst = new ArrayList<User>(); lst.add(new User(2, "u2")); lst.add(new User(3, "u3")); lst.add(new User(4, "u4")); lst.add(new User(5, "u5")); lst.add(new User(6, "u6")); return lst; } }
此時註解WebService內還有三個屬性:
endpointInterface表示webservice接口名,由於一個類能夠繼承多個接口,你必須指明哪一個是webservice接口
serviceName:表示當前webservice的別名
portName:表示當前webservice的端口名
這些屬性定義好以後,在wsdl中是能看到的,若是不定義,cxf會配置默認的別名和端口名
最後一步部署webservice:
public class Server { protected Server() throws Exception { // START SNIPPET: publish System.out.println("Starting Server"); HelloServiceImpl implementor = new HelloServiceImpl(); String address = "http://localhost:8111/helloWorld"; Endpoint.publish(address, implementor); // END SNIPPET: publish } public static void main(String[] args) throws Exception { new Server(); System.out.println("Server ready..."); Thread.sleep(5 * 60 * 1000); System.out.println("Server exiting"); System.exit(0); } }
web service是須要部署到服務器的,經過Endpoint.publish方法部署的話,我估計是部署到jetty上的,具體神馬狀況,由於我的經驗不足在這不胡說了。經過運行main函數就能夠啓動服務了,檢驗服務是否啓動,能夠訪問以下地址:http://localhost:8111/helloWorld?wsdl,若是能顯示正確的xml信息則表示服務啓動成功。
最後寫一個客戶端程序調用web service:
public final class Client { private static final QName SERVICE_NAME = new QName("http://ws.bless.com/", "HelloService"); private static final QName PORT_NAME = new QName("http://ws.bless.com/", "HelloServicePort"); private Client() { } public static void main(String args[]) throws Exception { Service service = Service.create(SERVICE_NAME); // Endpoint Address String endpointAddress = "http://localhost:8111/helloWorld"; // Add a port to the Service service.addPort(PORT_NAME, SOAPBinding.SOAP11HTTP_BINDING, endpointAddress); HelloService hw = service.getPort(HelloService.class); System.out.println(hw.sayHi("World")); System.out.println(hw.getUser(new User(1, "kaka"))); for(User user : hw.getListUser()){ System.out.println("List User [id:"+user.getId()+"][name:"+user.getName()+"]"); } } }
測試:
首先啓動server,若是沒問題的話,再啓動clien,你們能夠看控制檯的效果。
三、CXF與spring整合:
熟悉spring的朋友應該知道spring的IOC管理對象很是強大,那麼cxf與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-extension-soap.xml" /> <import resource="classpath:META-INF/cxf/cxf-servlet.xml" /> <jaxws:endpoint id="helloWorld" implementor="com.bless.ws.HelloServiceImpl" address="http://localhost:8080/webservice/helloService" /> <jaxws:client id="helloClient" serviceClass="com.bless.ws.HelloService" address="http://localhost:8080/webservice/helloService" /> </beans>
你們能夠經過java代碼測試(測試時把上一步配置的beans.xml文件放在src根下面):
public class SpringTest { public static void main(String[] args) { // START SNIPPET: client ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("beans.xml"); HelloService client = (HelloService)context.getBean("helloClient"); String response = client.sayHi("Joe"); System.out.println("Response: " + response); System.exit(0); // END SNIPPET: client } }
若是是web項目,那麼你須要配置web.xml文件:
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee" xmlns:web="http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" id="WebApp_ID" version="2.5"> <display-name>CxfDemo</display-name> <context-param> <param-name>contextConfigLocation</param-name> <param-value>WEB-INF/beans.xml</param-value> </context-param> <!--Spring ApplicationContext 載入 ,必須--> <listener> <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class> </listener> <!-- Spring 刷新Introspector防止內存泄露 --> <listener> <listener-class>org.springframework.web.util.IntrospectorCleanupListener</listener-class> </listener> <servlet> <servlet-name>CXFServlet</servlet-name> <servlet-class>org.apache.cxf.transport.servlet.CXFServlet</servlet-class> <load-on-startup>1</load-on-startup> </servlet> <servlet-mapping> <servlet-name>CXFServlet</servlet-name> <url-pattern>/webservice/*</url-pattern> </servlet-mapping> </web-app>