Java CXF介绍与实例

CXF简介

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 VS Axis2

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开发


使用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的整合部分会在另外一篇介绍。

不需要Web服务器的开发

首先, 需要到官方网站获取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文件中添加:

    org.apache.cxf
    cxf-rt-transports-http-jetty
    3.1.6

3.cxf调用报错Could not find conduit initiator for address:
SOAP的传输协议是基于http协议的,需要相关依赖
报错解决方案:
添加依赖:

    org.apache.cxf
    cxf-rt-transports-http
    3.2.2

你可能感兴趣的:(110-Java语言)