基础架构
CXF旨在为服务创建必要的基础设施,它的整体架构主要由以下几个部分组成:
1.Bus
它是C X F架构的主干,为共享资源提供了一个可配置的场所,作用非常类似于S p r i n g的ApplicationContext。这些共享资源包括WSDL管理器、绑定工厂等。通过对Bus进行扩展,可以方便地容纳自己的资源,或替换现有的资源。默认Bus实现是基于Spring的,通过依赖注入,将运行时组件串起来。Bus的创建由BusFactory负责,默认是 SpringBusFactory,对应于默认Bus实现。在构造过程中,SpringBusFactory会搜索META-INF/cxf(就包含在 CXF的Jar中)下的所有Bean配置文件,根据它们构建一个ApplicationContext。开发者也可提供自己的配置文件来定制Bus。
2.消息传递和拦截器(Interceptor)
CXF建立于一个通用的消息层之上,主要由消息、拦截器和拦截器链(InterceptorChain)组成。CXF是以消息处理为中心的,熟悉 JSP/Servlet的开发者可以将拦截器视为CXF架构中的“Filter”,拦截器链也与“FilterChain”类似。通过拦截器,开发者可以方便地在消息传递、处理的整个过程中对CXF进行扩展。拦截器的方法主要有两个:handleMessage和handleFault,分别对应消息处理和错误处理。在开发拦截器的时候需要注意两点:
拦截器不是线程安全的,不建议在拦截器中定义实例变量并使用它。这一点跟JSP/Servlet中对于Filter的处理是一样的;
不要调用下一个拦截器的handleMessage或handleFault,这个工作由InterceptorChain来完成。
3.前端(Front End)
它为CXF提供了创建服务的编程模型,当前主要的前端就是JAX-WS。
4.服务模型
CXF中的服务通过服务模型来表示。它主要有两部分:ServiceInfo和服务本身。ServiceInfo作用类似WSDL,包含接口信息、绑定、端点(EndPoint)等信息;服务则包含了ServiceInfo、数据绑定、拦截器和服务属性等信息。可使用Java类和WSDL来创建服务。一般是由前端负责服务的创建,它通过ServiceFactory来完成。
5.绑定(Binding)
绑定提供了在传输之上映射具体格式和协议的方法,主要的两个类是Binding和BindingFactory。BindingFactory负责创建Binding。
6.传输(Transport)
为了向绑定和前端屏蔽传输细节,CXF提供了自己的传输抽象。其中主要有两个对象:Conduit和Destination。前者是消息发送的基础,后者则对应消息接收。开发者还可以给Conduit和Destination注册MessageObserver,以便在消息发送和接收时获得通知。
开发方法
CXF 可以创建的Web 服务应用有两种:服务提供者和服务消费者。这种结构可类比客户端/ 服务器结构,服务消费者类似于客户端,服务提供者类似于服务器。使用CXF 创建应用时,服务提供者和服务消费者并不需要同时出现,因为有可能应用只是作为服务提供者或服务消费者单独出现。
为了说明使用CXF 如何创建这两种类型的应用,本教程将同时给出它们的例子。另外,由于Groovy在Java 世界中变得越来越流行,本教程会给出使用Groovy 的CXF 插件GroovyWS 的实现例子。例子使用JDK 1.5.X 和Groovy 1.0 完成,包含以下几部分:
1.User,用户对象,在消费者和提供者之间传递;
2.UserService,用户管理服务,它提供增加和获取所有用户的功能;
3.Client,服务消费者,它向UserService发起服务请求。
Java 实现的步骤包括以下几点。
服务端包含UserService、UserServiceImpl和User。其中,UserService是接口定义,UserServiceImpl是它的实现,并负责服务的发布,服务只有发布之后才能被消费。例子使用了JAX-WS,它们的主要内容如下:
UserService
package server;
import javax.jws.WebService;
@WebService
public interface UserService {
void add(User user);
User[] findAllUsers();
}
|
@WebService 指明接口是Web 服务
UserServiceImpl
import java.util.List;
import java.util.Vector;
import javax.jws.WebService;
import javax.xml.ws.Endpoint;
@WebService(endpointInterface = "server.UserService",
serviceName = "UserService",
portName="UserServicePort")
public class UserServiceImpl implements UserService {
static List<User> UserRepository= new Vector<User>();
public void add(User user) {
UserRepository.add(user);
}
public User[] findAllUsers() {
User[] users= new User[UserRepository.size()];
UserRepository.toArray(users);
return users;
}
public static void main(String[] args){
UserServiceImpl userService= new UserServiceImpl();
Endpoint.publish("http://localhost:9000/userService
", userService);
}
}
|
@ WebService中的serviceName、portName,分别指定了其产生的WSDL中的服务名和端口名。endpointInterface为接口的类名。服务发布代码也可以放在另一个类中。
User
package server;
public class User {
String first;
String last;
public String getFirst() {
return first;
}
public void setFirst(String first) {
this.first = first;
}
public String getLast() {
return last;
}
public void setLast(String last) {
this.last = last;
}
}
|
2.客户端只有一个类:Client,其他的User、UserService引用server包中的对象。
package client;
import javax.xml.namespace.QName;
import javax.xml.ws.Service;
import javax.xml.ws.soap.SOAPBinding;
import server.User;
import server.UserService;
public class Client {
public static void main(String[] arg){
Service service = Service.create(
new QName("http://server/
", "UserService"));
service.addPort(new QName("http://server/
", "UserServicePort")
, SOAPBinding.SOAP11HTTP_BINDING
, "http://localhost:9000/userService
");
UserService userService= service.getPort(UserService.class);
User user= new User();
user.setFirst("James");
user.setLast("Bond");
userService.add(user);
User[] users= userService.findAllUsers();
for(User u : users){
System.out.println(u.getFirst()+"."+u.getLast());
}
}
}
|
注意,QName 的第一个参数指明了WSDL 的目标名字空间,可以通过“服务地址?wsdl”方式获取服务的WSDL,来查看服务的目标名字空间。对于由CXF 创建的服务,目标名字空间的默认构造规则是:http:// 包名的倒序/。即如果包名是a.b.c,那么名字空间就为http://c.b.a/ 。GroovyWS 的实现步骤包括以下几点。
1.服务端包括:User、UserService、User.aegis.xml。由于Groovy类包含一个metaClass属性,该属性不应该被序列化在服务端和客户端之间传递,User.aegis.xml用来指定将该属性忽略掉。
User
package server;
class User {
String first
String last
}
|
UserService
package server;
import groovyx.net.ws.WSServer
class UserService {
private static List users= new Vector()
void add(User user){
users.add(user)
}
User[] findAllUsers(){
User[] u= new User[users.size()]
users.toArray(u)
return u
}
static void main(args) {
def server = new WSServer()
server.setNode("server.UserService",
"http://localhost:9000/UserService
")
}
}
|
注意它的发布。
Use.aegis.xml
<?xml version="1.0" encoding="UTF-8"?>
<mappings xmlns:sample="http://DefaultNamespace
">
<mapping name="sample:User">
<property name="metaClass" ignore="true"/>
</mapping>
</mappings>
|
2.客户端包含:Client和User.aegis.xml,User.aegis.xml的内容和服务端的一样。Client的内容如下:
package client;
import groovyx.net.ws.WSClient
class Client {
static void main(args) {
def proxy = new WSClient(
"http://localhost:9000/UserService?wsdl
", Client.class.classLoader)
def user= proxy.create("defaultnamespace.User");
user.first="James"
user.last="Bond"
proxy.add(user)
def result= proxy.findAllUsers()
result.users.each{
println it.first+"."+it.last
}
}
}
|
相关建议
CXF 的功能特性非常多,要熟练使用它非得花些功夫才行。笔者在此给出一些建议,期望能对读
者在今后学习和使用CXF 的过程中有所帮助:
1.熟悉工具涉及领域的协议是个不错的主意。虽然CXF提供了简化服务创建的编程模型,但是如果不了解WS-*协议,在遇到问题调试时必然会花不少时间。尤其是在SOA的环境中,客户端和服务不一定是使用同一语言、同一工具实现的情况下,互操作问题经常是由于对协议的不同支持造成的;
2.作为CXF实现内容的一个重点,JAX-WS是值得关注的;
3.在Java的环境中,Spring几乎已经成为开发服务器端应用的首选,应重点关注CXF和Spring的配合使用;
4.近些年来,Java世界的动态语言旋风愈演愈烈。Groovy由于其语法和Java兼容且提供了不少方便的语法,吸引了不少Java开发者。更何况新兴的Grails框架逐渐引人注目,其前途不可限量。GroovyWS专为Groovy开发,且底层就是CXF,作为CXF的开发者,没有理由不去使用可以使自己生活过得舒适的工具;
5.CXF携带了大量的例程,它们是熟悉和了解CXF的大门的;
6.参与社区,参与讨论,往往比起自己单干要有用得多。
版本信息
在官方网站上,CXF 公布了其2.0.4 版和2.1版的开发计划。2.0.4 版于2008 年1 月15 日发布,2.1 版则是2 月28 日发布。2.0.4 版的计划主要是修正2.0.3 版的错误,以及工具迁移的问题。2.1 版则引入一些新特性,包括:
1.支持JAX-WS 2.1,包括JAXB 2.1、API中的WS-A、SEI接口方法的JAXB标注、WebServiceFeature标注;
2.XmlBeans、JiBX数据绑定;
3.新的java2ws工具;
4.更好地支持REST(JSR-311);
5.支持js;
6.OSGi bundling。
除了上述计划,有可能包含在2.1 版,但是肯定会在2.2 版的特性包括:
1.通过继承Yoko 的代码来支持CORBA;
2.更好地集成Acegi;
3.WS-SecureConversation/Trust;
4.其他WS-*协议。
社区视角
在Celtix 和XFire 宣布合并的同年,另一个著名开源Web 服务框架Axis 的后继者Axis2 也诞生了。Axis2 并非Axis 的2.0 版,而是完全重写了Axis 的新项目。作为功能和背景都极其相似的两个项目,人们难免会将它们相提并论。在著名的Java 企业开发站点TheServiceSide 上就有一篇名为“Axis, Axis2 and CXF: Survey theWS Landscape”(地址:http://www.theserverside.com/tt/articles/content/AxisAxis2andCXF/article.html )的文章对这两个项目进行了比较,主要内容如下。
1.在特性方面:
C X F 支持W S - A d d r e s s i n g 、W S -Policy、WS-RM、WS-Security和WS-I BasicProfile。Axis2支持除了WSPolicy之外的所有这些标准,WS-Policy预计会在未来版本中得到支持;
CXF可以方便地和Spring集成在一起,Axis2不行;
Axis2支持范围更广的数据绑定,包括XMLBeans、JiBX、JaxMe、JaxBRI,以及它自己的数据绑定ADB。在 Axis21.2 版中,JaxME和JaxBRI尚处于试验阶段。目前,C X F只支持J A X B和Aegis,对XMLBeans、JiBX和Castor的支持将在CXF 2.1版中实现;
Axis2支持多语言,除了Java版本,尚有C/C++版本。
2.在开发方面:
Axis2更像一个微型服务器。Axis2被打包成一个WAR,可部署到任何Servlet容器中,为了更方便地在运行中管理和部署服务进行专门的设计。
CXF更专注于对开发人员友好及可嵌入性。大部分配置只需使用API即可完成,与Spring紧密集成。CXF强调代码优先的服务开发方式。
3.建议:如果需要多语言支持,那么就采用Axis2;如果考虑到使用Java、与Spring集成,或将服务嵌入到其他程序中,那么CXF更好。
当然,并不是所有人都说好。例如,在国内的一些论坛上,就有开发者抱怨CXF 的入门比起XFire 来要复杂得多。这是可以理解的,毕竟CXF本身也比XFire 要复杂得多。为了帮助Celtix 和XFire 的开发者向新工具的迁移,其官方网站也提供了相应的迁移指南。另外一个常见的问题是和Spring AOP 相关的(如事务、安全),这在官方网站的FAQ 中也有说明。
相关推荐
CXF 建立于一个通用的消息层之上,主要由消息、拦截器和拦截器链(InterceptorChain)组成。CXF 是以消息处理为中心的,熟悉 JSP/Servlet 的开发者可以将拦截器视为 CXF 架构中的“Filter”,拦截器链也与...
Apache CXF 框架是一个比较有前途的开源 Web Services 框架,也是构建 SOA 架构应用的利器。本书采用案例源码和解说形式全面介绍 Apache CXF 框架的功能。 本书共 15 章,大致分为三个部分。第一部分介绍关于 SOA 和...
apache cxf很好的教程,让你快速学习搞的定
Apache CXF Apache CXF Apache CXF Apache CXF Apache CXF Apache CXF Apache CXF Apache CXF Apache CXF
2013版的 <基于Apache CXF构建SOA应用> 源码 Apache CXF是一个开放源码的Web服务框架,提供了一个易于使用,用于开发Web Services标准为基础的编程模型。本书主要介绍Apache CXF在构建SOA架构各个方面的应用说明和...
Apache CXF = Celtix + XFire,Apache CXF 的前身叫 Apache CeltiXfire,现在已经正式更名为 Apache CXF 了,以下简称为 CXF。CXF 继承了 Celtix 和 XFire 两大开源项目的精华,提供了对 JAX-WS 全面的支持,并且...
apache cxf 2.1.3 的用户手册
Apache CXF 是一个开放源代码框架,提供了用于方便地构建和开发 Web 服务的可靠基础架构。
Apache CXF 中文教程 javax.jws.WebService
Apache CXF Web Service Development
apache cxf 3.1.8 java web service 开源框架
apache cxf 一个helloworld的例子
Apache CXF Web Service Development Developing+Web+Services+with+Apache+CXF+and+Axis2+(3rd+Edition)
Apache CXF = Celtix + XFire,Apache CXF 的前身叫 Apache CeltiXfire,现在已经正式更名为 Apache CXF 了,以下简称为 CXF。CXF 继承了 Celtix 和 XFire 两大开源项目的精华,提供了对 JAX-WS 全面的支持,并且...
webserviceApache CXF java springboot利用Apache CXF创建webserice接口 Apache CXF 核心架构是以BUS为核心,整合其他组件。 * Bus是CXF的主干, 为共享资源提供一个可配置的场所,作用类似于Spring的...
Apache CXF Web Service Development 源码
java通过cxf实现webservice所需jar包。java通过cxf实现webservice所需jar包。