java rpc学习之rest 学习之Resteasy 学习(9)

1 RestEasy简介

2 手把手教你使用Resteasy;

3 揭秘Resteasy的实现原理;

4 总结;

 

一、RestEasy 简介

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) 等。
 

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。

 

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

//java 规范

    javax.ws.rs
    javax.ws.rs-api
    2.1-m07

//resteasy 核心包

    org.jboss.resteasy
    resteasy-jaxrs
    3.1.3.Final


//resteasy 核心包

    org.jboss.resteasy
    resteasy-client
    3.1.3.Final


//json 序列化

    org.jboss.resteasy
    resteasy-jackson-provider
    3.1.3.Final




    org.jboss.resteasy
    resteasy-jaxb-provider
    3.1.3.Final




    org.jboss.resteasy
    resteasy-netty
    3.1.3.Final




    org.jboss.resteasy
    resteasy-jdk-http
    3.1.3.Final

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

java rpc学习之rest 学习之Resteasy 学习(9)_第1张图片

 

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

java rpc学习之rest 学习之Resteasy 学习(9)_第2张图片

 

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

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

java rpc学习之rest 学习之Resteasy 学习(9)_第3张图片

 

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

 

三、揭秘Resteasy的实现原理

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

 

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

 

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

 

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

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

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

java rpc学习之rest 学习之Resteasy 学习(9)_第4张图片

其中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中; 详见以下代码片段:

java rpc学习之rest 学习之Resteasy 学习(9)_第5张图片

 

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

java rpc学习之rest 学习之Resteasy 学习(9)_第6张图片

 

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

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

 

java rpc学习之rest 学习之Resteasy 学习(9)_第7张图片

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

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

 

java rpc学习之rest 学习之Resteasy 学习(9)_第8张图片java rpc学习之rest 学习之Resteasy 学习(9)_第9张图片

(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资源。
无论哪种方式原理都是一样的,只是初始化的时机不同。

你可能感兴趣的:(java,rpc_soa)