神奇好望角 The Magical Cape of Good Hope

庸人不必自扰,智者何需千虑?
posts - 26, comments - 50, trackbacks - 0, articles - 11
  BlogJava :: 首页 ::  :: 联系 :: 聚合  :: 管理

JAX-RS 从傻逼到牛叉 1:REST 基础知识

Posted on 2011-09-16 15:31 蜀山兆孨龘 阅读(5463) 评论(3)  编辑  收藏 所属分类: Java EESOA

JAX-RS(JSR 311 - Java™ API for RESTful Web Services,用于 REST 风格的 Web 服务的 Java™ API)是 Java EE 6 规范的一部分,其目标在于简化和标准化用 Java 开发 REST 风格的 Web 服务。虽然 Java EE 6 刚出炉的时候,楼主也从头到尾看过这份规范,但苦于没有实际的项目练手,看过又忘了,现在最多算达到大成傻逼的境界。这次边看边写,期望完成后至少能破入小成牛逼。先从 REST 本身开始。


REST(REpresentational State Transfer,代表性状态传输)自称是一种风格而非标准,这在楼主看来有炒作的嫌疑。如果仅仅是一种风格,那么不同的框架如何兼容?所以才有 JAX-RS 的诞生。REST 最大的贡献是带来了 HTTP 协议的复兴。为什么叫复兴呢?本来 HTTP 的功能挺丰富的,可惜长期以来只被用作传输数据,大好青年被埋没了。楼主记得刚开始学 Servlet 的时候,一向是把 doGetdoPost 两个方法一视同仁的,因为书上这么教,很多 Web 框架也这么搞,以至于弄了很久才搞清楚 GETPOST 是两种不同的请求。现在 REST 拍砖说道,HTTP 早就定义好了一堆操作,以前一直被混淆使用,现在应该重新赋予它们本来的意义了,而且如果充分发挥 HTTP 的功能,完全能够胜任分布式应用的开发(传说中的 SOA)。


SOA 的理念在于将系统设计为一系列可重用的、解耦的、分布式的服务。这也不是新鲜玩意儿了,早期有 CORBA,稍晚有 SOAP 等等。REST 作为后起之秀,能够快速崛起,也必有其非同寻常的特色。下面一一列举。

可寻址性(Addressability)

系统中的每个资源都可以通过唯一标识符来访问。小插一句,“标识”的正确读音是 biāozhì。REST 使用 URI(统一资源标识符)管理资源的地址。URI 的概念不解释。一个 URI 可以指向一个或者多个资源。

统一的受限接口(The Uniform, Constrained Interface)

实际上强调了 HTTP 操作的原意。REST 主要使用了 GET、PUT、DELETE、POST、HEAD 和 OPTIONS 这 6 种操作。此处有两个曾经被忽略的 HTTP 概念:幂等(idempotent)和安全(safe)。幂等应该是 HTTP 从数学借来的一个术语(原始的数学意义楼主也不懂),意味着若干次请求的副作用与单次请求相同,或者根本没有副作用。GET、PUT、DELETE、HEAD 和 OPTIONS 都是幂等的:GET、HEAD 和 OPTIONS 都是读操作,容易理解;PUT 用于创建或更新已知 URI 的资源,多次创建或更新同一个资源显然和一次的效果相同;DELETE 删除资源,亦然。安全表示操作不会影响服务器的状态。GET、HEAD 和 OPTIONS 是安全的。POST 既不幂等又不安全,因为和 PUT 不同,POST 创建资源的时候并不知道资源的 URI,所以多个 POST 请求将会创建多个资源。

面向表象(Representation-Oriented)

表象这个词有点拗口,传闻在一个 REST 风格的系统中,服务端和客户端之间传输的咚咚就是表象……表象可以是纯文本、XML、JSON……或者自编的山寨格式。唉,不就是数据么?只不过可以用任意的格式来传输,因为 HTTP 正文里面啥都能放。Content-Type 头用来声明格式,一般是 MIME(多用途因特网邮件扩展),像 text/plaintext/htmlapplication/pdf 这些。MIME 可以带属性,例如 text/html; charset=UTF-8

无态通信(Communicate Statelessly)

REST 服务器只管理资源,而不会像 Web 服务器一样记录客户的会话状态,这些应该由客户端来管理,如此就能增强 REST 服务器的伸缩性。此处的客户端可以是客户端程序、浏览器,甚至一个 Web 应用。总之,REST 只负责库管啦!

HATEOAS

猛词砸来了!HATEOAS = Hypermedia As The Engine Of Application State,超媒体作为应用状态的引擎,怎么看起来比 SaaS(Software as a Service,软件作为服务)还要吓人呢?超文本不过是一只纸老虎,超媒体也瞒不过楼主的天眼:超媒体就是是由文字、图像、图形、视频、音频……链成一体的大杂烩!很简单的一个例子,有些坑爹的电影网站经常发布一些内嵌了广告的电影,播放的时候会弹出广告窗口,里面很多链接,你去点两下就中招了:这个电影文件就算是超媒体。

其实这个词最关键的地方是“状态引擎”。例如楼主在去网购,先选了几个东西,接下来可以干啥呢?可以继续选、可以把购物车清空、可以结账……楼主可以从现状“转换”到其他某些状态,而控制状态转换的那个咚咚就被冠名为状态引擎。多么聪明的词汇啊!楼主发现凡是高手都是造词砖家呀!用超媒体来控制状态转换,就是 HATEOAS:你是要继续看电影还是看广告?看哪个广告?自己慢慢考虑……


REST 相比 CORBA、SOAP、WS-* 之流确实独树一帜,但也难逃玩弄概念的嫌疑。记得大学里讲数据库的老师说过:“你们现在学了这么多理论,其实以后在工作中未必管用。在大街上随便找一个软件培训学校出来的小伙子,他哪儿懂什么第二第三范式啊?但却能把数据库玩儿得飞转!”


评论

# re: JAX-RS 从傻逼到牛逼 1:REST 基础知识  回复  更多评论   

2011-09-29 23:41 by 李卫
POST 既不幂等又不安全,因为和 PUT 不同,POST 创建资源的时候并不知道资源的 URI,所以多个 POST 请求将会创建多个资源。
请问这句话是什么意思?为什么post请求可以创建多个资源,put就不会呢?

# re: JAX-RS 从傻逼到牛逼 1:REST 基础知识  回复  更多评论   

2011-09-30 17:41 by 蜀山兆孨龘
@李卫
这些其实都是 HTTP 约定的,如果你喜欢的话,完全可以让 POST 幂等而 PUT 不幂等。如果程序严格遵守 HTTP,在用 POST 请求创建资源的时候,是不知道所创建的资源的 URI,这个就用像 EntityManager#persist 持久化一个没有设定主键的实体一样,系统将自动生成主键,多次调用生成的主键不同,自然就创建了多个资源,所以不是幂等的。PUT 就像 EntityManager#merge,用于更新一个系统中已经存在的资源,所以主键是确定的,从而 URI 也确定了。用 PUT 请求多次更新同一个资源,效果和只更新一次相同,所以是幂等的。

# re: JAX-RS 从傻逼到牛叉 1:REST 基础知识  回复  更多评论   

2011-12-05 17:32 by 天空布蓝
没有看懂。。。。

只有注册用户登录后才能发表评论。


网站导航: