对电脑前的我们来说,万维网是我们生活的一个重要部分。早晨起来看报纸,付账单,买卖股票以及在线购买物件或者服务,都是通过浏览器访问万维网做到的。“百度”这个词成为我们生活的一个常用词汇,我们通过百度搜索一部待上映的电影什么时候可以看到,或者上网找多年不联系的老朋友。挨门挨户推销百科全书的推销员已无踪影,因为像维基百科等知识网站已经成为人类知识的重要来源。人们越来越喜欢社交网站,如Facebook和MySpace。更多专业的社交网站开始如雨后春笋般出现,涉及各行各业,如医生、律师等各种专业人才利用万维网进行交互协作。
作为一名程序员,万维网是我们日常工作的一部分。我们搜索下载开源的类库以帮助我们开发应用产品。我们开发web应用以使任何人可以通过浏览器访问到我们的系统。
实际上,我们中的很多人认为万维网是理所应当存在的。但作为一名程序员,有没有想过为什么万维网能如此成功?它如何从专业机构使用的简单的小型网络成长为全球互联的网络社区?哪些特性使万维网蔓延的如此之快?
一个人,Roy Fielding,他在它的博士论文中问了这些问题,“Architectural Styles and the Design of Network-based Software Architectures.”在这篇论文中,他认定了能够回答下面问题的架构原则。
为什么万维网如此流行?
什么使万维网如此规模?
如何将万维网的架构应用于我的程序应用?
这些架构原则被简称为REpresentational State Transfer (REST) ,表示性状态转移。定义如下:
已经标识的资源:在REST中,信息和数据被认为是一种资源,每个资源有通过URI进行标示。
统一的接口和约束:使用一个小的定义好的方法集合来操作你的资源。
面向表示的:你通过使用服务的表示来和服务进行交互。一个通过一个UR标识的资源可有不同的表示形式。不同的平台需要不同的形式。比如,浏览器需要HTML格式,JavaScript需要JSON格式,一个Java应用可能需要XML形式。
无状态通信:无状态的应用便于扩展。
超媒体作为应用状态的引擎(HATEOAS):让你的数据格式驱动你的应用的状态转移。
从博士论文的角度,Roy的论文实际上是比较容易阅读的,并且不是长篇阔论。这篇论文以及Leonard Richardson和Sam Ruby的著作RESTful Web Services是理解REST的最佳参考资料。这一章,我将更简短地介绍REST以及它使用的传输层协议。
REST and the Rebirth of HTTP(REST和HTTP的复兴)
REST不是特指某种协议,但是当人们讨论REST时,他们实际上在说基于HTTP的REST。学习了解REST对我来说,既是一个重新探索感受HTTP协议的过程,也是一个学习新的分布式应用架构风格的时候。基于浏览器的web应用只用到了HTTP所有特性的一小部分。非RESTful风格的技术,比如SOAP和WS-*等只是用HTTP作为传输层协议因此只用到HTTP所具有的能力集合中的一小部分。很多人说,SOAP和WS-*仅仅使用HTTP穿过防火墙。其实,HTTP是一个功能齐全的应用协议,它提供了很多有趣且有用的能力。在写REST风格的web应用之前,你需要对HTTP有一个深入的理解。
HTTP是一个同步的基于请求/响应模式的应用网络协议,它可用于分布式的、协作的、基于文档的系统。它是应用在万维网的一个基本协议,特别地,Firefox,MS Internet Explorer,Safari以及Netscape都用到HTTP。HTTP是一个简单的协议,客户端发送的请求消息有发起的HTTP方法、你感兴趣的资源的地址、一组头部、可选的消息体组成。消息体可以是你要的任何东西,包括HTML,文本text,XML,JSON,甚至二进制数据。下面是一个例子:
GET /resteasy/index.html HTTP/1.1
Host: jboss.org
User-Agent: Mozilla/5.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: en-us,en;q=0.5
Accept-Encoding: gzip,deflate
当你想查看 http://jboss.org/resteasy/index.html这个网址时,你的浏览器将会发送上面的请求消息。GET是你要调用的服务端的方法。/resteasy/index.html 是你感兴趣的实体。HTTP/1.1是协议的版本号标识。Host, User-Agent, Accept, Accept-Language, 以及 Accept-Encoding是消息头。这里没有消息体,因为我们使用GET方法从服务端获取数据。
从服务端返回的响应消息
HTTP/1.1 200 OK
X-Powered-By: Servlet 2.4; JBoss-4.2.2.GA
Content-Type: text/html
<head>
<title>JBoss RESTEasy Project</title>
</head>
<body> Visit
www.w3.org/Protocols/rfc2616/rfc2616-sec10.html
<h1>JBoss RESTEasy</h1>
<p>JBoss RESTEasy is an open source implementation of the JAX-RS specification...
响应码200,状态信息OK。这表示请求被正常处理并返回响应。HTTP有一个大的响应码集合。像200表示正常,500表示服务端内部错误。可以访问www.w3.org/Protocols/rfc2616/rfc2616-sec10.html 进行了解。响应消息包含了消息体,其有HTML组成,我们可以根据Content-Type头部得知。