Apache CXF 快速上手教程


ApacheApacheApacheApache CXF CXF CXF CXF 快 速上 手教 程 基 础架 构 CXF 旨 在为 服务 创建 必要 的基 础设 施, 它的 整体 架构 主要 由以 下几 个部 分组 成: 1.Bus 它是CXF架构的主干,为共享资源提供了一个可配置的场所,作用非常类似于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;@WebServicepublic 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 UserRepository= new Vector();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 firstString last} UserService package server;import groovyx.net.ws.WSServerclass 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/User Service")}} 注 意它 的发 布。 Use.aegis.xml 2.客 户端 包含 : Client 和User.aegis.xml,User.aegis.xml 的 内容 和服 务端 的一 样。 Client 的内 容 如下 : package client;import groovyx.net.ws.WSClientclass 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"p roxy.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.在 特性 方面 : CXF 支持WS–A d d r e s s i n g 、WS-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 尚 处于 试验 阶段 。目前,CXF只 支持 J AXB和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 中 也有 说 明。
还剩7页未读

继续阅读

下载pdf到电脑,查找使用更方便

pdf的实际排版效果,会与网站的显示效果略有不同!!

需要 15 金币 [ 分享pdf获得金币 ] 12 人已下载

下载pdf

pdf贡献者

robit110

贡献于2012-02-04

下载需要 15 金币 [金币充值 ]
亲,您也可以通过 分享原创pdf 来获得金币奖励!
下载pdf