Apache CXF 是一個開源的 Services 框架,CXF 幫助您利用 Frontend 編程 API 來構建和開發 Services ,像 JAX-WS 。這些 Services 可以支持多種協議,比如:SOAP、XML/HTTP、RESTful HTTP 或者 CORBA ,並且可以在多種傳輸協議上運行,比如:HTTP、JMS 或者 JBI,CXF 大大簡化了 Services 的創建,同時它繼承了 XFire 傳統,一樣可以天然地和 Spring 進行無縫集成。
先貼出maven項目的pom.xml,這里使用了spring,而且有坑,spring的版本選用太新會啟動不了服務器,后改為3.X版本才好。
1 <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 2 xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd"> 3 <modelVersion>4.0.0</modelVersion> 4 <groupId>com.bigbang</groupId> 5 <artifactId>cxf</artifactId> 6 <packaging>war</packaging> 7 <version>0.0.1-SNAPSHOT</version> 8 <name>cxf Maven Webapp</name> 9 <url>http://maven.apache.org</url> 10 <properties> 11 <cxf.version>3.1.11</cxf.version> 12 <spring.version>3.1.0.RELEASE</spring.version> 13 </properties> 14 <dependencies> 15 <dependency> 16 <groupId>junit</groupId> 17 <artifactId>junit</artifactId> 18 <version>3.8.1</version> 19 <scope>test</scope> 20 </dependency> 21 <dependency> 22 <groupId>org.apache.cxf</groupId> 23 <artifactId>cxf-rt-frontend-jaxws</artifactId> 24 <version>${cxf.version}</version> 25 </dependency> 26 <dependency> 27 <groupId>org.apache.cxf</groupId> 28 <artifactId>cxf-rt-transports-http</artifactId> 29 <version>${cxf.version}</version> 30 </dependency> 31 <!-- Jetty is needed if you're are not using the CXFServlet --> 32 <dependency> 33 <groupId>org.apache.cxf</groupId> 34 <artifactId>cxf-rt-transports-http-jetty</artifactId> 35 <version>${cxf.version}</version> 36 </dependency> 37 <dependency> 38 <groupId>org.springframework</groupId> 39 <artifactId>spring-context</artifactId> 40 <version>${spring.version}</version> 41 </dependency> 42 <dependency> 43 <groupId>org.springframework</groupId> 44 <artifactId>spring-web</artifactId> 45 <version>${spring.version}</version> 46 </dependency> 47 <dependency> 48 <groupId>org.springframework</groupId> 49 <artifactId>spring-beans</artifactId> 50 <version>${spring.version}</version> 51 </dependency> 52 </dependencies> 53 <build> 54 <plugins> 55 <plugin> 56 <groupId>org.mortbay.jetty</groupId> 57 <artifactId>maven-jetty-plugin</artifactId> 58 <version>6.1.26</version> 59 <configuration> 60 <webAppConfig> 61 <contextPath>/</contextPath> 62 </webAppConfig> 63 </configuration> 64 </plugin> 65 66 <plugin> 67 <groupId>org.apache.maven.plugins</groupId> 68 <artifactId>maven-compiler-plugin</artifactId> 69 <configuration> 70 <source>1.8</source> 71 <target>1.8</target> 72 </configuration> 73 </plugin> 74 </plugins> 75 <finalName>cxf</finalName> 76 </build> 77 78 </project>
項目web.xml文件的配置如下:
1 <context-param> 2 <param-name>contextConfigLocation</param-name> 3 <param-value>classpath*:/application*.xml</param-value> 4 </context-param> 5 <servlet> 6 <servlet-name>CXFServlet</servlet-name> 7 <servlet-class>org.apache.cxf.transport.servlet.CXFServlet</servlet-class> 8 <load-on-startup>1</load-on-startup> 9 </servlet> 10 <servlet-mapping> 11 <servlet-name>CXFServlet</servlet-name> 12 <url-pattern>/service/*</url-pattern> 13 </servlet-mapping> 14 <listener> 15 <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class> 16 </listener>
其中CXFServlet是要訪問的webservice入口配置。
Spring文件的相關配置如下:
1 <?xml version="1.0" encoding="UTF-8"?> 2 <beans xmlns="http://www.springframework.org/schema/beans" 3 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:jaxws="http://cxf.apache.org/jaxws" 4 xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd 5 http://cxf.apache.org/jaxws http://cxf.apache.org/schemas/jaxws.xsd"> 6 7 <import resource="classpath:META-INF/cxf/cxf.xml" /> 8 <import resource="classpath:META-INF/cxf/cxf-servlet.xml" /> 9 10 <bean id="loginService" class="com.bigbang.cxf.service.LoginServiceImpl"/> 11 <jaxws:endpoint implementor="#loginService" address="/login"/> 12 </beans>
需要引入jax-ws的命名空間。並且引入兩個xml配置文件,這兩個文件在cxf的包里面,可以不用關心。 此處配置了一個bean,該bean是實現webservice服務的實現類。里面是具體的業務邏輯。
jaxws:endpoint是配置webservice端地址的,implementor指向一個實現類,address是webservice的訪問地址。結合web.xml里面的cxfServlet配置,訪問webservice的地址應該為:http://IP:端口/項目名/service/login?wsdl
webservice的接口和實現類如下:
接口類:
1 package com.bigbang.cxf.service; 2 3 import javax.jws.WebParam; 4 import javax.jws.WebService; 5 6 /** 7 * @author pzj 8 * 9 */ 10 @WebService 11 public interface LoginService { 12 13 String login(@WebParam(name="name")String name,@WebParam(name="password")String password); 14 }
@webservice注解說明這是一個webservice類,@WebParam是指明webservice接口方法的參數名稱。類似於springmvc的@requestParam注解。此處如果不指明參數名稱,webservice的wsdl文件里將使用arg0,arg1...代替,在寫客戶端代碼請求webservice的時候,將引起困擾,不易編寫代碼。
實現類為:
1 package com.bigbang.cxf.service; 2 3 import javax.jws.WebService; 4 5 /** 6 * @author pzj 2017年5月16日 下午4:58:43 7 * 8 */ 9 @WebService(endpointInterface="com.bigbang.cxf.service.LoginService") 10 public class LoginServiceImpl implements LoginService { 11 12 /* (non-Javadoc) 13 * @see com.bigbang.cxf.LoginService#login(java.lang.String, java.lang.String) 14 */ 15 @Override 16 public String login(String name, String password) { 17 return name+"登錄成功!密碼是:"+password; 18 } 19 20 }
和上面接口不同的是,此處需要指明終端接口類的地址(包名+類名)。
全部准備好之后,使用jetty啟動,會顯示如下啟動信息:
五月 18, 2017 9:58:05 上午 org.apache.cxf.wsdl.service.factory.ReflectionServiceFactoryBean buildServiceFromClass 信息: Creating Service {http://service.cxf.bigbang.com/}LoginServiceImplService from class com.bigbang.cxf.service.LoginService 五月 18, 2017 9:58:06 上午 org.apache.cxf.endpoint.ServerImpl initDestination 信息: Setting the server's publish address to be /login 2017-05-18 09:58:06.173:INFO:oejs.AbstractConnector:Started SelectChannelConnector@0.0.0.0:8080
說明webservice發布成功了,訪問http://localhost:8080/service/login?wsdl,會生成xml頁面:
1 This XML file does not appear to have any style information associated with it. The document tree is shown below. 2 <wsdl:definitions xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/" xmlns:tns="http://service.cxf.bigbang.com/" xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/" xmlns:ns1="http://schemas.xmlsoap.org/soap/http" name="LoginServiceImplService" targetNamespace="http://service.cxf.bigbang.com/"> 3 <wsdl:types> 4 <xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:tns="http://service.cxf.bigbang.com/" elementFormDefault="unqualified" targetNamespace="http://service.cxf.bigbang.com/" version="1.0"> 5 <xs:element name="login" type="tns:login"/> 6 <xs:element name="loginResponse" type="tns:loginResponse"/> 7 <xs:complexType name="login"> 8 <xs:sequence> 9 <xs:element minOccurs="0" name="name" type="xs:string"/> 10 <xs:element minOccurs="0" name="password" type="xs:string"/> 11 </xs:sequence> 12 </xs:complexType> 13 <xs:complexType name="loginResponse"> 14 <xs:sequence> 15 <xs:element minOccurs="0" name="return" type="xs:string"/> 16 </xs:sequence> 17 </xs:complexType> 18 </xs:schema> 19 </wsdl:types> 20 <wsdl:message name="login"> 21 <wsdl:part element="tns:login" name="parameters"></wsdl:part> 22 </wsdl:message> 23 <wsdl:message name="loginResponse"> 24 <wsdl:part element="tns:loginResponse" name="parameters"></wsdl:part> 25 </wsdl:message> 26 <wsdl:portType name="LoginService"> 27 <wsdl:operation name="login"> 28 <wsdl:input message="tns:login" name="login"></wsdl:input> 29 <wsdl:output message="tns:loginResponse" name="loginResponse"></wsdl:output> 30 </wsdl:operation> 31 </wsdl:portType> 32 <wsdl:binding name="LoginServiceImplServiceSoapBinding" type="tns:LoginService"> 33 <soap:binding style="document" transport="http://schemas.xmlsoap.org/soap/http"/> 34 <wsdl:operation name="login"> 35 <soap:operation soapAction="" style="document"/> 36 <wsdl:input name="login"> 37 <soap:body use="literal"/> 38 </wsdl:input> 39 <wsdl:output name="loginResponse"> 40 <soap:body use="literal"/> 41 </wsdl:output> 42 </wsdl:operation> 43 </wsdl:binding> 44 <wsdl:service name="LoginServiceImplService"> 45 <wsdl:port binding="tns:LoginServiceImplServiceSoapBinding" name="LoginServiceImplPort"> 46 <soap:address location="http://localhost:8080/service/login"/> 47 </wsdl:port> 48 </wsdl:service> 49 </wsdl:definitions>
