天天看点

Java RESTful Web Service实战(第2版) 1.2 解读REST服务

<b>1.2 解读rest服务</b>

restful对应的中文是rest式的,restful

web service的准确翻译应该是rest式的web服务,我们通常简称为rest服务。restful的应用或者web服务是最常见的两种rest式的项目部署、存在的方式。本节将介绍rest服务并对比其与传统web services的不同。

<b>1.2.1 rest式的web服务</b>

restful web service是一种遵守rest式风格的web服务。rest服务是一种roa(resource-oriented

architecture,面向资源的架构)应用。其主要特点是方法信息存在于http协议的方法中(比如get、put),作用域存在于uri中。例如,在一个获取设备资源列表的get请求中,方法信息是get,作用域信息是uri中包含的对设备资源的过滤、分页和排序等条件。

<b>1.2.2 对比rpc风格</b>

相比web服务领域广为流行的rpc(remote procedure call protocol,远程过程调用协议)风格,rest风格更轻量和快速。从方法信息角度看,rest采用标准的http方法,而rpc请求都是http协议的post方法,其方法信息包含于soap协议包或http协议包中,方法名称不具有通用性。从作用域角度看,rest采用uri显式定义作用域,而rpc的这一信息同样包含于协议包中,不能直观呈现。

rpc风格的开发关注于服务器–客户端之间的方法调用,而不关注基于哪个网络层的哪种协议。也就是说,rpc是面向方法调用过程的,相比而言,rest是面向资源状态的。rpc风格的两个代表是xml-rpc和大web服务。

1. xml-rpc

xml-rpc是一种使用xml格式封装方法调用,并使用http协议作为传送机制的rpc风格的实现。xml-rpc的请求方法都是http协议的post方法,请求和响应的数据格式均为xml。

xml-rpc的数据格式和使用xml作为资源的表述的rest外观上很相似,但数据的内容则大相径庭。rest式的xml信息的主体是对一个资源状态的表述,无须包含方法信息,因为其请求的http方法就已经决定了这一点。xml-rpc的请求数据结构额外包含方法调用信息和参数信息。

对于响应信息的内容两者也截然不同,rest式通常会包含响应实体信息,以及http状态码和可选的异常信息,而xml-rpc的返回信息仅仅是对方法调用的响应信息。

xml-rpc是一种遗留技术,已经被soap取代。在java领域,jax-rpc标准已经并入jax-ws2标准。xml-rpc的应用依然存在,著名的测试用例管理系统testlink的对外接口就是使用php开发的xml-rpc。

2. 大web服务

大web服务(big web service)是leonard richardson和sam ruby在其所著的《restful web services》一书中,对基于soap+ wsdl+uddi+ws-标准栈等技术实现rpc风格的大型web服务的统称。事实上,“大web服务”这一说法也被java ee 7的布道者们在多次演讲中使用。在java领域,对应的标准主要是jax-ws 2.0/2.1/2.2(jsr 224)。相较rest式的web服务,大web服务功能更强大,设计更复杂。大web服务同样是跨平台、跨语言的,对复杂的数据类型的支持也非常好。大web服务是基于rpc风格的重量设计,因此方法和作用域无法通过直观断定,需要定义在消息中,而且方法名不是统一和通用的。同时,大web服务走http协议时,请求都是基于post方法的。

对比rpc风格的web服务,rest式的web服务形式更简单、设计更轻量、实现更快捷。rest无须引入soap消息传输层,无须注册服务,也没有客户端stub的概念等。但是,rest式的web服务并没有像大web服务那样提供诸如安全策略等全面的标准规范。

大web服务和rest式的web服务各有优势,并不是一种替换关系。在实际开发中,两者共存于一个项目中也是一种解决方案。

<b>1.2.3 对比mvc风格</b>

mvc风格的出现将模型、视图、控制解耦,其亮点是从前到后的一致性,其结构整洁、逻辑清晰,易于扩展和增强。mvc在java领域的普遍实现方式是在web前端使用标签库来对应服务端的模型类实例和控制类实例,标签库和服务端依赖库可以是松散的耦合,比如spring生态系统,也可以是全栈式的统一体系,比如jsf体系。但无论如何实现,在web前端的开发过程中,必须时刻考虑页面标签和服务端的映射关系,包括模型类的匹配和转换、数据结构、控制类的输入和输出的参数类型和数量等。

因此,mvc风格偏重于解决服务器端的逻辑分层问题,以及客户端是逻辑分层的延伸问题。mvc的标签库虽然其形态已经和html页面融合,但本质上还是java编写的装饰模式的类实例,对应的是服务器端使用java编写的模型类或者控制器类,因此mvc很难实现跨语言解耦。而rest风格偏重于统一接口,因此具体实现就可以跨平台和跨语言。rest推动了web开发的新时代,使用平庸的纯html作为客户端,没有服务器端和客户端的耦合。显而易见,使用纯html开发的rest客户端和使用java开发的rest服务器端并不存在语言上的耦合。

mvc和rest式并不是互斥的,如spring的mvc模块已经开始支持rest式的开发。jersey作为jax-rs标准的实现,也实现了mvc的功能,请参考相关模块:jersey-mvc、jersey-mvc-freemarker和jersey-mvc-jsp。需要说明的是,本书致力于讲述jax-rs,对于jersey实现中的jax-rs之外的功能,只做必要的讲述。由于mvc和rest之间有更多的并行存在性,本书余文没有将mvc放入讲述之列。