Resteasy ,从学会使用到了解原理

Stella981
• 阅读 728

转载本文需注明出处:EAII企业架构创新研究院,违者必究。如需加入微信群参与微课堂、架构设计与讨论直播请直接回复此公众号:“加群 姓名 公司 职位 微信号”。

1、背景知识

1.1)了解Rest是什么?

1.2)了解JAX-RS是什么?

1.3)RestEasy简介

2、手把手教你使用Resteasy

3、揭秘Resteasy的实现原理

4、总结

一、Rest简介及Resteasy产生背景

1.1)了解Rest是什么:

REST是英文RepresentationalState Transfer 的缩写,有中文翻译为“具象状态传输”。REST 这个术语是由 RoyFielding 在他的博士论文《Architectural Styles and the Design ofNetwork-based Software Architectures 》中提出的。REST并非标准,而是一种开发 Web 应用的架构风格,可以将其理解为一种设计模式。REST 基于 HTTP,URI,以及 XML 这些现有的广泛流行的协议和标准,伴随着 REST,HTTP 协议得到了更加正确的使用。

相较于基于 SOAP 和 WSDL 的 Web 服务,REST 模式提供了更为简洁的实现方案。目前,越来越多的 Web 服务开始采用 REST 风格设计和实现,真实世界中比较著名的 REST 服务包括:Google AJAX 搜索 API、Amazon Simple Storage Service (AmazonS3) 等。

基于 REST 的 Web 服务遵循一些基本的设计原则:

1)系统中的每一个对象或是资源都可以通过一个唯一的 URI 来进行寻址,URI 的结构应该简单、可预测且易于理解,比如定义目录结构式的 URI。

2)以遵循RFC-2616 所定义的协议的方式显式地使用 HTTP 方法,建立创建、检索、更新和删除(CRUD:Create, Retrieve, Update and Delete)操作与 HTTP 方法之间的一对一映射:

若要创建资源,应该使用 POST方法, URI : xxx/book(在服务器端新建图书信息,需提供该图书所有信息)

若要检索某个资源,应该使用 GET 方法, URI:xxx/book/{ID} (从服务器端获得某图书信息)

若要更改资源状态或对其进行更新,应该使用 PUT 方法,URI:xxx/book/{ID}(在服务器端更新某已存在的图书信息,需提供更新的内容)

若要删除某个资源,应该使用 DELETE 方法, URI :xxx/book/{ID} (从服务器端删除某图书信息)

URI 所访问的每个资源都可以使用不同的形式加以表示(比如 XML 或者 JSON),具体的表现形式取决于访问资源的客户端,客户端与服务提供者使用一种内容协商的机制(请求头与 MIME 类型)来选择合适的数据格式,最小化彼此之间的数据耦合。

1.2) 了解JAX-RS是什么?

Java EE 6 引入了对 JSR-311 的支持。JSR-311(JAX-RS:JavaAPI for RESTful Web Services)旨在定义一个统一的规范,使得 Java 程序员可以使用一套固定的接口来开发 REST 应用,避免了依赖于第三方框架。同时,JAX-RS 使用 POJO 编程模型和基于标注的配置,并集成了JAXB,从而可以有效缩短 REST 应用的开发周期。

JAX-RS是一套用java实现REST服务的规范,提供了一些标注将一个资源类,一个POJOJava类,封装为Web资源. 这些标注包括以下:

@Path:标注资源类或方法的相对路径。

@GET,@PUT,@POST,@DELETE:标注方法是用的HTTP请求的类型。

@Produces:标注返回的MIME媒体类型。

@Consumes:标注可接受请求的MIME媒体类型。

@PathParam,@QueryParam,@HeaderParam,@CookieParam,@MatrixParam,@FormParam:分别标注方法的参数来自于HTTP请求的不同位置,例如@PathParam来自于URL的路径,@QueryParam来自于URL的查询参数,@HeaderParam来自于HTTP请求的头信息,@CookieParam来自于HTTP请求的Cookie。

更通俗些说如果你用java写了一套框架,当开发者自己写的JAVA类使用了JAX-RS定义的这些注解标注过,然后通过你写的这套框架就可以将有这些JAX-RS标注的类发布成web资源,供其他客户端程序去调用。那么你写的这套框架就是一套RestFul Web Service框架,就是JAX-RS规范的实现者之一,是JAX-RS标准定义的这些标注的解释执行者。

目前比较流行的JAX-RS实现有以下几种:

Apache CXF,开源的Web服务框架开源组织Apache的实现。

Jersey,由Sun提供的JAX-RS的参考实现。

RestEasy,JBoss的JAX-RS的实现。

与其他几个框架相比较而言,RestEasy以其高性能,轻量级,简单易上手,高可靠性和稳定性以及易于与其他容器集成等特点,越来越受到开发人员的欢迎。

1.3)Resteasy简介:

RESTEasy是JBoss的一个开源项目,提供一套完整的框架帮助开发人员构建RESTful Web Service和RESTful Java应用程序。它是JAX-RS 2.0规范的一个完整实现并通过JCP认证,通过Http协议对外提供基于Java API的 RestFul Web Service。

RestEasy可以运行在任何Servlet容器中,作为JBoss的官方实现它可以更好的和Jboss服务器紧密融合从而提供更好的用户体验。

作为JAX-RS的标准实现,RestEasy还具有以下亮点特性:

1)不需要配置文件,只要把JARs文件放到类路径里面,添加 @Path等标注就可以了

2)完全的把 RESTEeasy 配置作为Seam 组件来看待

3)HTTP 请求由Seam来提供,不需要一个额外的Servlet

4)Resources 和providers可以作为Seam components (JavaBean or EJB),具有全面的Seaminjection,lifecycle, interception, 等功能支持

5)支持在客户端与服务器端自动实现GZIP解压缩

6)支持异步请求处理

7)支持多种数据传输格式: XML, JSON, YAML, Fastinfoset, Multipart, XOP, Atom

……

二、手把手教你使用Resteasy

Resteasy的配置方法有很多种,本节内容是为了给下节讲解RestEasy原理做个铺垫,便于大家理解其实现原理,所以使用了RestEasy最基础的配置方式,其他配置方法大家可以去官网找到相关资料。

RestEasy的配置使用非常的简单,现在我们通过一个 Demo来看一下如何使用RestEasy。

  • 新建一个JAVA Web工程: 我使用了Maven来创建webapp项目:

Resteasy ,从学会使用到了解原理

Resteasy ,从学会使用到了解原理

Resteasy ,从学会使用到了解原理

  • 引入依赖包:pom.xml 配置如下:

Resteasy ,从学会使用到了解原理

  • 新建Java 资源类,并添加相应的注解;(要发布成rest服务的类)

Resteasy ,从学会使用到了解原理

  • 配置web.xml,添加使用Resteasy将资源类发布成rest服务的能力,配置如下:

Resteasy ,从学会使用到了解原理

  • 验证,启动服务器打开浏览器访问:

http://localhost:8080/resteasydemo/path1/subpath/123

Resteasy ,从学会使用到了解原理

出现以上结果说明通过Resteasy发布 Rest服务成功.怎么样 SoEasy吧。

三、揭秘Resteasy的实现原理

通过上面的Demo相信大家都已经学会如何使用Resteasy把一个JavaBean发布成Rest服务了,接下来我们结合Demo一起来看一下Resteasy的实现原理。

我本人研究Resteasy实现原理的方法是:通过上面这个Demo来调试阅读Resteasy的源码进而理解其实现原理。

首先要发布restful的service要解决以下几个问题:

  1. 谁来接受来自客户端的请求,并进行分发交给对应的对象的方法去处理。

  2. 负责处理客户端请求的对象由谁来负责产生(上面Demo中的TestRest对象)。

  3. 如何解析Java类上面的JAX-RS注解,使客户端过来的请求可以找到对应的对象的方法去执行。

带着上面的三个问题我们来看一下Resteasy是如何设计实现来解决上面的问题的。

在上面的Demo中要把TestRest发布成Rest服务首先在web.xml文件中做了以下配置:

Resteasy ,从学会使用到了解原理

其中ResteasyBootstrap作为监听器是拉起Resteasy服务的入口,在服务启动时主要做了以下动作:

1)通过ListenerBootstrap组件读取在web.xml文件中的一些系统配置信息,创建ResteasyDeployment对象,并将这些配置信息初始化到该对象中,其中就包括将”resteasy.resources”中配置的资源类的路径初始化到其成员变量resourceClasses中;

2)通过调用ResteasyDeployment的start()方法,并根据相关配置信息初始化Resteasy的核心组件ResteasyProviderFactory ,Dispatcher,Registry.

3)最关键的部分是调用registration(),在该方法中会遍历之前在web.xml中配置的资源并将其注册到Registry中, 以Demo中的例子来看会遍历resourceClasses中配置好的TestRest资源路径,并加载该类然后通过调用registry.addPerRequestResource(clazz)注册到Registry中; 详见以下代码片段:

Resteasy ,从学会使用到了解原理

在addPerRequestResource()中做了两个主要的事情:其中一个是会使用相应的ResourceFactory来包装资源类TestRest,见以下代码片段:

Resteasy ,从学会使用到了解原理

通过阅读POJOResourceFactory的源码可以了解到其作用就是包含了资源类的所有元信息,因此它可以利用ResteasyProviderFactory提供的注入器在需要时通过createResource()来创建资源类TestRest的对象;

第二个主要的事情是Registry可以通过资源类中的元信息来解析上面的JAX-RS注解,并将该注解的路径和对应的方法生成的invoker对象注册到Registry中,在Demo中就是把”/path1/subpath/{id}”和 test()方法的invoker对象注册到Registry中。

Resteasy ,从学会使用到了解原理

(Resteasy在服务启动时初始化过程图)

在web.xml文件中另一个配置是配置了HttpServletDispatcher,该类是HttpServlet的实现是所有请求的入口,通过其service()方法最终将请求交给之前启动服务时已经初始化好的Dispatcher对象来处理. 以Demo为例,当请求”http://localhost:8080/resteasydemo/path1/subpath/123”过来时,Dispatcher对象会调用其成员变量Registry对象来解析该请求中的路径”/path1/subpath/123”, 然后匹配到相应的invoker来执行客户端请求(详见以下代码段),并将结果返回,页面会显示”Hello 123”;

Resteasy ,从学会使用到了解原理

Resteasy ,从学会使用到了解原理

(Resteasy 客户端请求处理流程图)

四、总结

通过对Resteasy源码的解读分析我们就可以解答刚开始的三个问题:

1)谁来接受来自客户端的请求,并进行分发交给对应的对象的方法去处理。

----->HttpServletDispatcher,(接受并分发客户端http请求)

2)负责处理客户端请求的对象由谁来负责产生。

----->ResourceFactory (在服务器启动时通过web.xml读取class的配置信息然后通过反射机制产生)

3)如何解析Java类上面的注解,使客户端过来的请求可以找到对应的方法去执行。

------>Registry(服务器启动时加载用户自定义Rest资源时,会解析上面的注解,并将注解相对路径和该类中执行的方法建立对应关系注册到Registry中,当客户端请求过来时会根据请求中的相对路径去Registry中查找对应的invoker对象,然后执行并将处理结果返回)

Resteasy就是通过以上几个核心组件的相互配合,最终将一个JavaBean发布成Rest服务,这种基于服务注册的实现方式,使得Resteasy具有较好的可扩展性,例如它能很好的和Spring进行整合将SpringBean发布成Rest服务,它是如何做到的呢?首先扩展了Resteasy的ResourceFactory实现了一个SpringResourceFactory(用来从Spring容器中获得对象),然后在服务启动时当Spring容器初始化好以后,通过扩展Spring的BeanFactoryPostProcessor,将Spring容器中初始化好的SpringBean以及对应的SpringResourceFactory注册到Resteasy的Registry中.这样客户端请求过来后,当请求路径在Registry中匹配到相应的SpringBean时就可以调用该SpringBean的ResourceFactory的createResource方法,该方法可以从Spring容器中获得对象来处理请求。

Tips:

Resteasy发布Rest服务的两种方式:

一种是通过listener (ResteasyBootstrap)方式在server启动时通过该listener的contextInitialized()初始化Resteasy核心组件及Rest资源。

第二种是如果没有在web.xml中配置ResteasyBootstrap监听器,则在HttpServletDispatcher,第一次请求过来时通过servlet的init方法初始化Resteasy核心组件及Rest资源。

无论哪种方式原理都是一样的,只是初始化的时机不同。

******关于作者:
******王磊

现任普元SOA产品部高级软件工程师,曾供职于Newegg,The ActiveNetWork等知名外企,在Newegg工作期间曾担任项目经理带领团队完成美蛋网O2O平台LocalPros的开发上线,在J2EE企业级应用方面有丰富的实战经验。

Resteasy ,从学会使用到了解原理

关于EAII

EAII(Enterprise Architecture Innovation Institute)企业架构创新研究院,致力于软件架构创新与实践,加速企业数字化转型。

eaworld项目(微信号:eaworld,长按二维码关注)

eaworld是EAII的官方微信账号。

以“企业数字化变革中的技术与架构创新”为主题的PWorld 2016大会即将召开!来自普元、红领集团、蓝月亮实业、星环科技的20余位技术大咖、近30场技术分享与你共议企业数字化未来!大会已于8月26日北京9月6日上海举行、将于9月20日****广州举办,感兴趣的可以扫二维码了解活动报名参与,欲了解详情请戳:阅读全文。

本文分享自微信公众号 - EAWorld(eaworld)。
如有侵权,请联系 support@oschina.cn 删除。
本文参与“OSC源创计划”,欢迎正在阅读的你也加入,一起分享。

点赞
收藏
评论区
推荐文章
Stella981 Stella981
3年前
React Native 移动技术在企业架构的应用
转载本文需注明出处:EAII企业架构创新研究院(微信号:eaworld),违者必究。如需加入微信群参与微课堂、架构设计与讨论直播请直接回复此公众号:“加群姓名公司职位微信号”。『发送关键字“ReactNative”至此公众号,获取完整PPT下载』!(https:
Stella981 Stella981
3年前
DevOps之应用自动化发布与资源管理
本文为普元云计算架构设计群的微课堂原创分享,转载需注明出处:EAII企业架构创新研究院。如需加入微信群参与微课堂、架构设计与讨论直播请直接回复此公众号:“加群姓名公司职位微信号”。大家好,我是郝炎峰,目前负责新一代数字化企业云平台“ThePlatform”中的基础服
Stella981 Stella981
3年前
DevOps的支撑服务:K8s容器管理与应用部署
本文为云计算架构设计群的微课堂原创分享,转载需注明出处:EAII企业架构创新研究院。如需加入微信群参与微课堂、架构设计与讨论直播请直接回复此公众号:“加群姓名公司职位微信号”。大家好,本期微课堂介绍在新一代数字化企业云平台中对于Kubernetes的学习以及使用的总结。
Stella981 Stella981
3年前
React风格的企业前端技术
转载本文需注明出处:EAII企业架构创新研究院,违者必究。如需加入微信群参与微课堂、架构设计与讨论直播请直接回复此公众号:“加群姓名公司职位微信号”。『发送关键字“React风格”至此公众号,获取完整PPT下载』大家好,首先祝大家国庆节快乐!很高兴可以在国庆前
Stella981 Stella981
3年前
Serverless架构:用服务代替服务器
转载本文需注明出处:EAII企业架构创新研究院(微信号:eaworld),违者必究。如需加入微信群参与微课堂、架构设计与讨论直播请直接回复此公众号:“加群姓名公司职位微信号”。还记得在十多年前,SaaS鼻祖SalesForce喊出的口号『NoSoftware』吗?SalesForce在这个口号声中开创了SaaS行业,并成为当今市值5
Stella981 Stella981
3年前
PWorld2016大会演讲PPT+访谈视频大合集,总有一款是你在找的!
转载本文需注明出处:EAII企业架构创新研究院,违者必究。如需加入微信群参与微课堂、架构设计与讨论直播请直接回复此公众号:“加群姓名公司职位微信号”。!(https://oscimg.oschina.net/oscnet/2a606f63f5ce4bd096ee24daeb14de42.
Stella981 Stella981
3年前
DevOps之自动化测试
转载本文需注明出处:EAII企业架构创新研究院,违者必究。如需加入微信群参与微课堂、架构设计与讨论直播请直接回复此公众号:“加群姓名公司职位微信号”。『微信后台回复“DevOps测试”,获取完整PPT下载』大家好,我是冀博,目前负责新一代数字化企业云平台“ThePlatform”
Stella981 Stella981
3年前
DevOps之软件产品管理最佳实践
转载本文需注明出处:EAII企业架构创新研究院,违者必究。如需加入微信群参与微课堂、架构设计与讨论直播请直接回复此公众号:“加群姓名公司职位微信号”。『微信后台回复“SPM”,获取完整PPT下载』大家好,我是王召,现在负责新一代数字化企业云平台“The
Stella981 Stella981
3年前
Docker 与 K8s 在企业基础设施服务的应用
转载本文需注明出处:EAII企业架构创新研究院(微信号:eaworld),违者必究。如需加入微信群参与微课堂、架构设计与讨论直播请直接回复此公众号:“加群姓名公司职位微信号”。『发送关键字“Docker”至此公众号,获取完整PPT下载』大家好,本次内容我在我司上个
Stella981 Stella981
3年前
Flannel+K8s容器网络通信实践
转载本文需注明出处:EAII企业架构创新研究院,违者必究。如需加入微信群参与微课堂、架构设计与讨论直播请直接回复此公众号:“加群姓名公司职位微信号”。亲爱的各位朋友,大家好!今天很高兴可以和大家分享我们普元云平台SEM使用kubernetes时,关于pod、service网络通讯