Java RESTful Web Service实战
上QQ阅读APP看书,第一时间看更新

1.4 Jersey项目概要

Jersey是JAX-RS标准的参考实现,是Java领域中开发REST式的Web服务的“正统”工具。这样讲述的目的是避免读者混淆REST领域诸多工具的地位,并无偏好推荐之意。本节将带领读者走进Jersey的世界。

Jersey项目是GlassFish项目的一个子项目,专门用来实现JAX-RS(JSR 311和JSR 339)标准,并提供了扩展特性。

1.获得Jersey

Jersey项目的网址是https://jersey.java.net,这是Jersey的官方网站。该网站同时提供了JAX-RS和JAX-RS 2.0两个并行版本,分别是Jersey 1.1(截至本书发稿,最新版本是Jersey 1.18)和Jersey 2.0(截至本书发稿,最新版本是Jersey 2.9)。读者可以通过单击“latest Jersey User Guide”获取和阅读最新版本的用户手册,这是官方发布的第一手的参考资料。

Jersey项目的下载地址https://jersey.java.net/download.html,Jersey项目使用Maven管理项目,该页面至上而下分别是:

□JAX-RS标准列表链接。

□Jersey最新参考实现的jar包下载。

□Jersey最新参考实现的示例代码下载。

□创建基于Maven管理的JAX-RS容器Jersey应用。

□创建基于Maven管理的Servlet容器Jersey应用。

□JAX-RS 1.1的参考实现包下载。

2.Jersey源代码

Jersey 2使用GitHub管理源代码,GitHub的客户端非常简洁。单击首页下方的“Source Control”进入https://jersey.java.net/scm.html页面,该页面提供了如何使用GIT来克隆Jersey的源代码的介绍。Jersey源代码的托管地址是https://github.com/jersey/jersey(见图1-1)。

图1-1 Jersey源代码仓库

如图1-1所示,Jersey项目的源代码是使用Maven构建的多模块项目。每个目录代表一个模块,比如core-server目录就是Jersey的Server模块。bom目录是个特殊的目录,是Maven的元数据目录,用于多模块Maven项目的组织和定义。通过浏览该页面可以观察到Jersey框架的模块,本章随后会介绍Jersey的各个模块。第2章将对基于Maven管理的Jersey应用做详细的讲述和演示。

小白讲堂

Maven(http://maven.apache.org/)是Apache开源组织的项目,该项目用于构建和组织Java的项目。读者如果对Maven不熟悉,推荐阅读许晓斌(Juven Xu)所著的《Maven实战》(机械工业出版社出版)。

如果读者对命令行不熟悉或者没有兴趣,可以使用GUI工具来完成源代码的管理。对于托管在GitHub的项目,可以使用GitHub官方提供的客户端来管理源代码,Windows版本下载地址:http://windows.github.com,Mac版本下载地址:http://mac.github.com。这款工具的使用非常简单,如图1-2所示,左侧树包括本地仓库和GitHub远程仓库两个结点。右侧是仓库列表,示意图中包括本书的示例项目jax-rs2-guide、第11章示例项目jax-rs2-atup和Jersey源代码等仓库。需要指出的是,其处理版本冲突的能力不足,需要借助命令行来完成。

图1-2 GitHub客户端示意图

小白讲堂

GIT是一种开源的分布式SCM(Source Code Management,源代码管理)工具,下载地址为http://git-scm.com/download。读者如果对GIT不熟悉,推荐阅读蒋鑫所著的《Git权威指南》(机械工业出版社出版)。

GitHub是GIT服务器中比较知名和成功的,它提供了基于身份认证的项目托管等功能。时下非常多的知名开源软件都将版本控制迁移到GIT并使用GitHub托管。如果可以,希望读者能从https://help.github.com/中得到更多信息。

3.Jersey问答

StackOverflow是专业的程序员问答系统,Jersey提供了其问题列表地址:http://stackoverflow.com/questions/tagged/jersey。从中可以看出开源社区对问答系统的重视。另外,邮件列表也是一种知识共享的途径,读者可以自行订阅,地址是:https://jersey.java.net/mailing.html。

实践趣事

这里想和读者分享的是,一名不断成长的程序员与年龄无关,个人很厌恶30岁分界的观点。一定是勤奋和富有热情的,这是开源社区和StackOverflow这样的问答系统的生存基石。社区和个人的成长是相辅相成的。推荐读者在遇到问题时,第一个想到的是搜Google、搜StackOverflow,而不是张嘴就问,问周边的人应该是正确做法中最后的办法。顺便要说的是,英语是程序员绕不开的技能,一起加油吧!

4.Jersey项目管理

Jersey使用JIRA作为项目管理平台,地址是https://java.net/jira/browse/JERSEY。JIRA和StackOverflow不同的是,这个平台是Jersey团队日常开发的管理平台,也就是说,这是Jersey官方的缺陷管理平台,用于上报缺陷和改进意见,而不是社区性质的交流平台。我们可以从中了解到Jersey项目的进展情况。Jersey是一个非常活跃的项目,不仅可以从GitHub的源代码的提交活动中看到该项目频繁的更新,在JIRA中,也可以看到该项目推进的速度。

宅人坑事

这里为喜欢开源社区活动的读者举个例子。我在撰写本书的开始,Jersey 2.0并不支持与Spring的集成,因为Jersey的IoC容器由GlassFish的另一个子项目HK2来支持。随后,我在JIRA上发现一个Jersey 2.x支持与Spring集成的任务被创建了(https://java.net/jira/browse/JERSEY-1957),此后我经常观察其进展状态,最终看到了这个功能在Jersey 2.2中以扩展包的形式发布了。因此,当使用Jersey时,如果遇到Jersey本身的问题,可以跟踪Jersey的JIRA平台来查看Bug的修复状态,包括将在哪个版本修复,有什么样的临时解决办法(workaround)。同时,跟踪JIRA也可以了解新版本的发布情况,包括新增哪些功能,升级给哪一部分带来性能、安全的提升等。换句话说,JIRA展示了Jersey项目的缺陷修复和新功能发版的计划(roadmap)。

5.Jersey许可

开发者使用开源软件的前提是了解它的许可证版本,否则可能会带来侵权问题。相信在正规的公司,大家都有被开发管理部门的人“恐吓”的经历。开发者需感谢开发管理部门所做的工作,他们为公司规避了商业侵权的风险,因为引用的源代码如果出自“传染性”许可,该项目是不能用于闭源的商业用途的。

Jersey的许可证说明地址是:https://jersey.java.net/license.html。从中我们可以了解到Jersey使用的是双许可证:CDDL(Common Development and Distribution License,开源通用开发和分发许可证)1.1和GPLv2(类路径例外)许可证。双重许可是依照两套(或更多套)不同的条款和条件分发相同软件的做法。在为软件授予双重许可时,接收人可以选择他们希望依照哪种条款获得软件。使用双重许可的两个常见动机是遵循商业模式和保持许可证兼容性。GPLv2.0许可证为无法依照CDDL许可证使用Jersey的供应商提供了一个额外选项。Jersey许可证使整套产品和包保持一致(GlassFish项目同样依照CDDL和GPLv2(类路径例外)授予双重许可)。

6.Jersey的模块

Jersey框架是由核心模块、容器模块、连接器模块、Media模块、扩展模块、测试框架模块和GlassFish Bundle模块7个大的模块组成。这不是一成不变的,随着Jersey的不断发展和完善,会有新的模块加入进来。推荐读者浏览官方文档,最新版本的地址为:https://jersey.java.net/documentation/latest/modules-and-dependencies.html,从而获得最新的信息。

小白讲堂

类路径例外是由自由软件基金会的GNU/类路径项目制定的。它允许用户将依照任何许可证提供的应用程序链接到依照GPLv2许可的软件中包含的库,而该应用程序不受GPL要求公开其本身的限制。为什么需要使用类路径例外?因为作为“基于[GPL]程序的作品”的一部分提供的所有代码还应获得GPL许可。因此,需要指定GPL许可证例外情况,以便明确将链接到GPL实现的任何应用程序从该许可要求中排除。类路径例外实现了这一目的。

(1)核心模块

Jersey核心模块由通用包、服务器实现和客户端实现3个子模块组成,是使用Jersey必需的依赖,见表1-2。

表1-2 Jersey核心模块列表

(2)容器模块

Jersey提供了3种对应于外部容器的HTTP容器,分别是Grizzly 2、JDK-HTTP和SIMPLE-HTTP,Grizzly 2同时提供了Servlet容器。对于Servlet的实现,Jersey提供了对Servlet 2.x和Servlet 3.x两个版本的实现。它们对应的包名见表1-3,详情可参考第2章。

表1-3 Jersey容器模块列表

(3)连接器模块

Jersey客户端底层依赖连接器实现网络通信,如果标准的客户端模块无法实现功能需求,可以考虑引入Grizzly连接器或者Apache连接器,见表1-4,详情可参考第5章。

表1-4 Jersey连接器模块列表

(4)Media模块

Jersey Media模块是支持Jersey处理传输数据媒体类型的模块。该模块提供了4种处理JSON的方式,分别是Jackson、Jettison、MOXy和JSON-P。另外,Multipart包用于对Form表单的支持,SSE用于对Server Sent Events支持,见表1-5,详情可参考第3章。

表1-5 Jersey Media模块列表

(5)扩展模块

Jersey生态环境中包含了许多JAX-RS 2.0标准之外的功能,比如MVC、Bean验证等辅助REST实现的模块,还有像Spring支持包这样的对第三方框架支持的模块见表1-6。

表1-6 Jersey扩展模块列表

(6)测试框架模块

Jersey提供了非常易用且功能强大的测试框架,见表1-7。测试框架提供了测试过程中完整的服务器端和客户端功能,通过测试框架,开发者可以减少很多模板代码的编写。详情可参考7.1节。

表1-7 Jersey测试框架模块列表

(7)GlassFish Bundle模块

GlassFish Bundle模块是Jersey提供的用于以Bundle方式支持GlassFish服务器的模块,包括CDI和EJB集成的扩展包,见表1-8。

表1-8 GlassFish Bundle模块列表

宅人坑事

Jersey在2.6版本做了一次包重构,清除了对Guava和ASM的自然依赖。如果读者的项目需要做Jersey版本迁移,需要注意这一点。新的包名为:jersey.repackaged.com.google.common和jersey.repackaged.objectweb.asm。

7.GlassFish项目

GlassFish项目地址为https://glassfish.java.net。GlassFish比较著名的是Java EE服务器项目Oracle GlassFish Server,该项目还同时包含Java EE中包含的一系列标准规范的参考实现,这些参考实现集成于GlassFish Server,为其Java EE容器提供支持。其中对JAX-RS 2.0的实现项目是Jersey。

为什么要在JAX-RS 2.0的介绍中提及GlassFish项目集呢?因为Jersey处于GlassFish生态环境中,GlassFish又是Java EE生态环境的实现描述。举个例子,当你需要在REST项目中访问数据库时,也许出于首选基于标准的实现的考虑,你会选择使用JPA。而JPA的参考实现EclipseLink就是GlassFish项目集的成员。这就像在你观赏深海的一条鱼的时候,势必有兴趣了解它会以哪些生物为生,又为哪些生物提供了生存保障。通过了解GlassFish项目,可以更好地完成REST式的Web服务。尤其,当你用户用NetBeans作为开发工具时,GlassFish服务器和GlassFish项目集是你生产中的“日用消费品”。

这里所列的项目是除Jersey以外其他的GlassFish项目,排列顺序并不严谨,大体上以其与Jersey的紧密关系降序排列。

(1)HK2

HK2项目地址为http://hk2.java.net。HK2是轻量级DI架构,实现IoC和DI的内核,是Jersey实现容器内管理Bean的基础,见表1-9。

表1-9 HK2项目情况简表

(2)Grizzly

Grizzly的项目地址为https://grizzly.java.net。Grizzly是一个异步I/O的、高效而健壮的服务器,可以用作HTTP服务器、Servlet容器,支持AJP、Comet、WebSocket,以及相对于RESTFul的另一种Web Service实现JAX-WS,见表1-10。

表1-10 Grizzly项目情况简表

如何使用和配置Grizzly依赖于用户的需求,也就是说,用户的项目不必加载Grizzly提供的全部jar包。表1-11列出了Grizzly项目的各个模块信息,可以参考该表定义用户的项目对Grizzly的依赖。

表1-11 Grizzly模块列表

(3)EclipseLink

EclipseLink项目地址为http://www.eclipse.org/eclipselink。EclipseLink是JPA 2.1的一个实现,同时它还实现了其他的JSR作为扩展。JPA 2.1是Java EE 7的成员,是对JSR 317(JPA 2.0)的升级。在JPA 2.1的实现中,最常用的是JBoss的Hibernate,该项目从4.3版本开始实现JPA 2.1。也就是说,Hibernate 4.2是JPA 2.0的最后一个版本。读者在开发的时候要注意依赖项目版本对标准的支持。EclipseLink项目情况见表1-12。

表1-12 EclipseLink项目情况简表

JPA标准还有其他的实现,可参考http://en.wikipedia.org/wiki/Java_Persistence_API。

(4)Metro

Metro项目地址为https://metro.java.net。Metro是JSR中多个标准的官方实现集,目的是实现全栈式的Web Service。Metro项目情况见表1-13。

表1-13 Metro项目情况简表

Metro项目中的多个标准的作用各有不同。

□JAX-WS标准结合了XML-RPC使用SOAP协议来实现Web Service。JAX-WS实现中,不可不提的另外两个实现分别是Apache的CXF和Axis。

□WSIT的前身是Tango,是一种JAX-WS和.NET互操作的技术,实现了WS*标准。

□SAAJ规范的作用是基于SOAP协议XML格式传递带附件的SOAP消息。

□JAXP标准涵盖了Java对XML过程式处理的诸多技术,包括DOM、SAX和StAX,同时该标准定义了解读XML样式的XSLT。

□JAXB标准是Java处理XML和POJO映射的技术,是Jersey中处理传输数据的重要依赖。

(5)Open MQ

Open MQ项目地址为https://mq.java.net。Open MQ是JMS 2.0的参考实现。JSR 343是Java EE 7的成员,旨在简化JMS的API。关于消息队列的实现数量,恐怕是其他任何一个标准都望尘莫及的。几乎每一个有能力开发服务器软件、中间件的公司都有自己的MQ,可参考http://en.wikipedia.org/wiki/Message_queue。目前支持JMS 2.0的其他实现并不多,HornetQ 2.4.0+兼容JMS 1.1和JMS 2.0是为数不多的JMS 2.0的其他实现。Open MQ简介见表1-14。

表1-14 Open MQ项目情况简表

(6)Mojarra

Mojarra项目地址为https://Java SErverfaces.java.net。Mojarra是JSF 2的官方实现。JSF是一种全栈式的、事件驱动的B/S开发模式框架,它包括浏览器端的丰富组件,服务器端覆盖Java EE的各种特性,见表1-15。JSF相对于Spring,借鉴了其核心思想IoC和AOP,同时给出了标准规范。这有点类似JPA借鉴了Hibernate的O/R Mapping思想并标准化。

表1-15 Mojarra项目情况简表

JSF的另一个实现是Apache的MyFaces,当前版本为2.0.18。另外,JBoss的RichFaces是基于JSF的扩展中最为完善和常用的。更多有关JSF的内容和原理,可参考笔者的《JSF 2和RichFaces 4使用指南》。

(7)OpenJDK

OpenJDK项目地址为http://openjdk.java.net。OpenJDK是开源的JDK,从1.7版本开始成为官方JDK的先行版本,因此是Java开发者研究Java发展的第一线的资源。同时也是活跃的Linux发行版本Ubuntu和Fedora等默认安装的JDK版本。OpenJDK项目情况见表1-16。

表1-16 OpenJDK项目情况简表

小白讲堂

下面讲一下JDK版本号升级规则。

自JDK 5.0发布开始,Java一直以两种方式发布更新。

1)有限升级(Limited Update):包含新功能和非安全修正。

2)重要补丁升级(Critical Patch Updates,CPUs):只包含安全修正。

有限升级发行序号为20的倍数,即一个偶数;重要补丁升级序号为顺延上一个CPUs的版本号+5的倍数并取奇数(必要时+1)。

举例来说,下一个有限升级的版本号为7u40,那么接下来的3个CPUs版本号依次为40+5=7u45、45+5+1=7u51和51+5=7u55。再下一个有限升级的版本号为7u60,随后的CPUs版本号依次为7u65、7u71和7u75。

这种命名规则会为重要补丁升级保留几个版本序号,以便新的CPUs版本号可以取区间值和而不是在最新版本号上顺延。