使用spring mvc或者resteasy构建restful服务
看到最近一个项目里用resteasy来构建restful接口,有点不明白,不少Spring mvc4.0以后也可以很方面的实现restful服务吗,为啥还要在Spring MVC的项目里还引入resteasy?估计还是开发人员根据自己技术能力自由选择的吧,毕竟resteasy引入也很简单。为了解惑,了解了一下resteasy。
resteasy 是 jboss的一个开源restful service实现参考。本文假设读者熟悉spring mvc,但是不了解或者没有使用过resteasy的用户。
其实一直以来,笔者实际都是使用spring mvc,对于研究resteasy没有兴趣。至于最近研究resteasy,纯属因为现在公司使用dubbox作为rpc框架,而dubbox使用resteasy作为REST实现库。
简单地说,resteasy核心就是一个servlet前端控制器,理念都一样。
应该来说,resteasy的优势在于相比spring mvc而言,更加的专注,简单。就大型应用而言,绝对是spring mvc占据优势。
就简洁性而言,应该来说在spring 4.0引入spring restcontroller之后,优势就没有那么明显了,应该来说3.2之前对restful还不那么有信心。
就像我们现在发现基本上mvc上spring mvc占据了绝大部分的新项目,估计以后resteasy也会小众化。
至于说resteasy为什么活下来,感觉上spring社区有个比较明显的倾向就是好像不怎么吃螃蟹,等到趋势比较明朗之后,要么就整合对方,要么就强行自己引入一套接口玩死对方。
resteasy是JAX-RS的参考实现之一,规范制定者是核心人员之一,所以概念和属于上基本上完全各种restful service教材上能够直接对应。spring mvc方面,就没有那么直接的对应了,估计是鄙视J2EE的一种商业手法。
就应用而言,如果restful作为rpc的实现机制,resteasy应该是有优势的,毕竟集成没有spring mvc那么多配置(当然spring cloud除外),但作为应用,估计干不过spring mvc。
resteasy的实现原理也与Spring MVC 的rest有相似的地方,可能后者也是借鉴前者的吧
先在web.xml文件中做了以下配置:
其中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中; 详见以下代码片段:
在addPerRequestResource()中做了两个主要的事情:其中一个是会使用相应的ResourceFactory来包装资源类TestRest,见以下代码片段:
通过阅读POJOResourceFactory的源码可以了解到其作用就是包含了资源类的所有元信息,因此它可以利用ResteasyProviderFactory提供的注入器在需要时通过createResource()来创建资源类TestRest的对象;
第二个主要的事情是Registry可以通过资源类中的元信息来解析上面的JAX-RS注解,并将该注解的路径和对应的方法生成的invoker对象注册到Registry中,在Demo中就是把”/path1/subpath/{id}”和 test()方法的invoker对象注册到Registry中。
(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源码的解读分析我们就可以解答刚开始的三个问题:
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容器中获得对象来处理请求。
Resteasy发布Rest服务的两种方式:
一种是通过listener (ResteasyBootstrap)方式在server启动时通过该listener的contextInitialized()初始化Resteasy核心组件及Rest资源。
第二种是如果没有在web.xml中配置ResteasyBootstrap监听器,则在HttpServletDispatcher,第一次请求过来时通过servlet的init方法初始化Resteasy核心组件及Rest资源。
无论哪种方式原理都是一样的,只是初始化的时机不同。http://blog.csdn.net/skydivingwang/article/details/77961872
使用spring mvc或者resteasy构建restful服务的更多相关文章
- 关于使用spring mvc或者resteasy构建restful服务的差别与比较
resteasy 是 jboss的一个开源java api for restful service(JSR 311,sun 2008年发布,最新GA版本是2.0, JAX-RS 2.0 (JSR-33 ...
- 使用 Spring 3 MVC HttpMessageConverter 功能构建 RESTful web 服务
原文地址:http://www.ibm.com/developerworks/cn/web/wa-restful/ 简介: Spring,构建 Java™ 平台和 Enterprise Edition ...
- Springboot & Mybatis 构建restful 服务五
Springboot & Mybatis 构建restful 服务五 1 前置条件 成功执行完Springboot & Mybatis 构建restful 服务四 2 restful ...
- Springboot & Mybatis 构建restful 服务二
Springboot & Mybatis 构建restful 服务二 1 前置条件 成功执行完Springboot & Mybatis 构建restful 服务一 2 restful ...
- Springboot & Mybatis 构建restful 服务
Springboot & Mybatis 构建restful 服务一 1 前置条件 jdk测试:java -version maven测试:命令行之行mvn -v eclipse及maven插 ...
- 手把手教你用Spring Cloud和Docker构建微服务
什么是Spring Cloud? Spring Cloud 是Pivotal提供的用于简化分布式系统构建的工具集.Spring Cloud引入了云平台连接器(Cloud Connector)和服务连接 ...
- Spring boot学习1 构建微服务:Spring boot 入门篇
Spring boot学习1 构建微服务:Spring boot 入门篇 Spring Boot是由Pivotal团队提供的全新框架,其设计目的是用来简化新Spring应用的初始搭建以及开发过程.该框 ...
- 使用 Spring Cloud 和 Docker 构建微服务架构
如何使用Spring Boot.Spring Cloud.Docker和Netflix的一些开源工具来构建一个微服务架构. 本文通过使用Spring Boot.Spring Cloud和Docker构 ...
- 用Jersey构建RESTful服务7--Jersey+SQLServer+Hibernate4.3+Spring3.2
一.整体说明 本例执行演示了用 Jersey 构建 RESTful 服务中.怎样集成 Spring3 二.环境 1.上文的项目RestDemo 2.Spring及其它相关的jar ,导入项目 三.配置 ...
随机推荐
- EntityFramewok 插入Mysql数据库 中文产生乱码解决
首先Mysql表,建表的时候,有没有选择UTF8,如果是默认的编码latin1,就会产生乱码 这里修改后,还是乱码,那就要检查发生乱码的列是不是UTF8格式 然后修改App.Config或者Web.C ...
- 分布式文件管理系统MooseFS在centOS 7中的安装
首先,MooseFS是做什么的在这边不做具体详述,这边主要记录一下我在自己部署MooseFS中遇到的问题和步骤(大部分参考的其他博客或者资料) 首先是准备资源,MooseFS的最新安装包可以去官网下载 ...
- Unity引擎的Player Settings介绍
我用的是unity5.4.3版本的 一.窗口打开: 从菜单栏查看播放器设置,选择 Edit->Project Settings->Player 二.全局设置 第一部分: Company N ...
- [Intermediate Algorithm] - Binary Agents
题目 传入二进制字符串,翻译成英语句子并返回. 二进制字符串是以空格分隔的. 提示 String.charCodeAt() String.fromCharCode() 测试用例 binaryAgent ...
- We wanted {"required":["value"]} and you sent ["text","value","id","sessionId"]
重装python pycharm后再次执行以前执行没有问题的Appium脚本报错 We wanted {"required":["value"]} and yo ...
- 团体程序设计天梯赛-练习集-L1-034. 点赞
L1-034. 点赞 时间限制 200 ms 内存限制 65536 kB 代码长度限制 8000 B 判题程序 Standard 作者 陈越 微博上有个“点赞”功能,你可以为你喜欢的博文点个赞表示支持 ...
- C语言编程-9_4 字符统计
输入一个字符串(其长度不超过81),分别统计其中26个英文字母出现的次数(不区分大.小写字母),并按字母出现次数从高到低排序,若次数相同,按字母顺序排列.字母输出格式举例,例如:A-3,表示字母A出现 ...
- H3C交换机配置常用命令(转)
1.配置文件相关命令 [Quidway]display current-configuration //显示当前生效的配置 [Quidway]display saved-configuration / ...
- switch 语句的反汇编浅析
switch 的简单情景(case 不超过 3 项) 首先,我们分析一下 switch 语句的一种简单情景,我们可以用 C 写出如下如下代码. 编译后用 OllyDBG 载入,它将显示出如下的反汇编代 ...
- HDU1087 - Super Jumping! Jumping! Jumping!【动态规划】
zh成功的在他人的帮助下获得了与小姐姐约会的机会,同时也不用担心被非"川大"的女票发现了,可是如何选择和哪些小姐姐约会呢?zh希望自己可以循序渐进,同时希望挑战自己的极限,我们假定 ...





