CXF是一个Java 版的Web Service框架
CXF是由过去的Celtix和XFire两个框架合并而来,CXF在java社区有广泛的接受度是得益于它能很好的集成Spring。
CXF最突出的两个优势是:
1.对JAX-WS规范的完整实现。 作为java平台上的WebService标准,过去既有的WebService产品必然会向这一标准靠拢,而JAX-WS标准本身大大地降低了开发WebService的工作量,对于开发人员来说,是非常受欢迎的。
2.对Spring的友好支持。 CXF从Xfire继承而来,对Spring有着非常友好的支持。鉴于Spring的广泛应用,对很多团队来说这是非常有吸引力的一点。
官方网站:http://cxf.apache.org/
CXF和Axis2是目前java平台上最主流的两个框架,虽然两个项目都隶属ASF,但却是基于不同思想和风格实现的,因此也各有所长。
1.CXF支持 WS-Addressing,WS-Policy, WS-RM, WS-Security和WS-I Basic Profile。Axis2不支持WS-Policy,但是承诺在下面的版本支持。
2. CXF可以很好支持Spring。Axis2不能
3. AXIS2支持更广泛的数据并对,如XMLBeans,JiBX,JaxMe和JaxBRI和它自定义的数据绑定ADB。注意JaxME和JaxBRI都还是试验性的。CXF只支持JAXB和Aegis。在CXF2.1
4. Axis2支持多语言-除了Java,他还支持C/C++版本。
如果你需要多语言的支持,你应该选择AXIS2。如果你需要把你的实现侧重JAVA并希望和Spring集成,CXF就是更好的选择,特别是把你的Web Service嵌入其他的程序中
通过网络渠道的了解,目前CXF的效率要比AXIS2高出至少50%
另外有一个webService的工具metro的效率比CXF高出10%
性能比较:
https://www.ibm.com/developerworks/cn/java/j-jws14/
使用CXF可以进行Web Service 的服务端和客户端的开发。
服务端就是使用Java发布Web Service服务,(CXF框架会转化为WSDL.)
客户端则是使用Java调用Web Service服务,(CXF框架可以将WSDL转化为java代码)。
所以在对WSDL不是很熟悉的情况下, 也可以也容易的进行Web Service的开发和调用。
客户端的调用,相对简单;这里主要说一下CXF服务端的开发。
CXF服务端开发的方式主要有三种:
1. 不需要Web服务器的开发。
一般我们的认知是Web Service需要部署在Web容器下才能生效和看到效果, 这个认知没有错。
只是CXF有自带一个轻量的容器服务,在没有Tomcat等Web服务器的状况下可以进行Web Service的发布和测试。
所以用来开发的项目可以一个简单的Java 项目。
2. 基于Web的开发
一个web 项目, 部署在服务器中。
3. 结合Spring进行开发。
在Spring 中整合CXF.
好了, 接下来就介绍第1种服务端开发的方式和客户端调用的实例, 基于Web的开发和Spring的整合部分会在另外一篇介绍。
首先, 需要到官方网站获取CXF. 这里使用的版本是 3.2.4
http://www.apache.org/dyn/closer.lua/cxf/3.2.4/apache-cxf-3.2.4.zip
将jar档加入到项目的lib中;如果是使用Maven,则加入如下部分:
org.apache.cxf
cxf
3.2.4
pom
接下来就开始实际的代码部分了
1. 定义接口.
/**
* @Title: MyWebServiceI.java
* @Package com.oscar999
* @Description: TODO
* @author oscar999
* @date May 23, 2018 11:34:39 AM
* @version V1.0
*/
package com.oscar999.cxf;
import javax.jws.WebParam;
import javax.jws.WebService;
/**
* @ClassName: MyWebServiceI
* @Description: TODO
* @author oscar999
*/
@WebService
public interface MyWebServiceI {
String sayHi(@WebParam(name = "text") String text);
}
2. 实现接口
/**
* @Title: MyWebServiceImpl.java
* @Package com.oscar999
* @Description: TODO
* @author oscar999
* @date May 23, 2018 11:37:02 AM
* @version V1.0
*/
package com.oscar999.cxf;
import javax.jws.WebParam;
import javax.jws.WebService;
/**
* @ClassName: MyWebServiceImpl
* @Description: TODO
* @author oscar999
*/
@WebService(endpointInterface = "com.oscar999.cxf.MyWebServiceI", serviceName = "Hello")
public class MyWebServiceImpl implements MyWebServiceI {
public String sayHi(@WebParam(name = "text") String text) {
return "Hello," + text;
}
}
3. 发布服务
/**
* @Title: MyWebServiceServer.java
* @Package com.oscar999
* @Description: TODO
* @author oscar999
* @date May 23, 2018 1:12:27 PM
* @version V1.0
*/
package com.oscar999.cxf;
import javax.xml.ws.Endpoint;
/**
* @ClassName: MyWebServiceServer
* @Description: TODO
* @author oscar999
*/
public class MyWebServiceServer {
/**
* @Title: main
* @Description: TODO
* @param args
*/
public static void main(String[] args) {
// TODO Auto-generated method stub
System.out.println("web service start...");
MyWebServiceImpl myWebService = new MyWebServiceImpl();
String address = "http://localhost:8080/myWebService";
Endpoint.publish(address, myWebService);
System.out.println("web service started");
}
}
以Java Application的方式运行这个程式,在浏览器输入:
http://localhost:8080/myWebService?wsdl
接可以看到对应的WSDL了。
客户端调用需要导入其他的一些lib 包, 使用maven的话,加入以下依赖配置:
org.apache.cxf
cxf-rt-frontend-jaxws
3.2.4
org.apache.cxf
cxf-rt-transports-http
3.2.4
org.apache.cxf
cxf-rt-transports-http-jetty
3.2.4
org.codehaus.woodstox
stax2-api
4.1
org.codehaus.woodstox
woodstox-core-asl
4.4.1
基于以上服务端的客户端代码:
/**
* @Title: MyWebServiceClient.java
* @Package com.oscar999.cxf
* @Description: TODO
* @author oscar999
* @date May 23, 2018 2:06:28 PM
* @version V1.0
*/
package com.oscar999.cxf;
import org.apache.cxf.jaxws.JaxWsProxyFactoryBean;
/**
* @ClassName: MyWebServiceClient
* @Description: TODO
* @author oscar999
*/
public class MyWebServiceClient {
/**
* @Title: main
* @Description: TODO
* @param args
*/
public static void main(String[] args) {
// TODO Auto-generated method stub
JaxWsProxyFactoryBean jwpfb = new JaxWsProxyFactoryBean();
jwpfb.setServiceClass(MyWebServiceI.class);
jwpfb.setAddress("http://localhost:8080/myWebService");
MyWebServiceI myWebService = (MyWebServiceI) jwpfb.create();
System.out.println(myWebService.sayHi("Oscar999"));
}
}
运行一下, 就可以看到效果了。
如果在以上实例中出现相关错误,可参考:
1. 客户端测试需要加上 cxf-rt-frontend-jaxws、 cxf-rt-transports-http 和 cxf-rt-transports-http-jetty。
如果出现如下异常还需要 woodstox-core-asl ,
SEVERE: Cannot find any registered HttpDestinationFactory from the Bus
stax2-api默认会有 3.1.4 , 但是运行的时候报
java.lang.RuntimeException: Cannot create a secure XMLInputFactory 的错误
是stax2-api版本低了, 加上stax2-api的4.1 版本。
2.在使用cxf过程中经常出 Cannot find any registered HttpDestinationFactory from the Bus,一般是没有引入cxf-rt-transports-http-jetty-xxx.jar。查看apache.cxf.transport.http.HTTPTransportFactory.getDestination(HTTPTransportFactory.java:270)类,jettyFactory为null,也就是缺少http-jetty的实现。
解决办法:
在pom.xml文件中添加:
3.cxf调用报错Could not find conduit initiator for address:
SOAP的传输协议是基于http协议的,需要相关依赖
报错解决方案:
添加依赖: