`
sslaowan
  • 浏览: 373834 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

对比REST之前和REST之后的URI映射

阅读更多

     2008年9月23日,JSR3111.0草案通过了JCP执行委员会的赞成投票 ,这基本意味着它现在已经定稿。

JAX-RS是Java中用于实现以HTTP为基础的RESTful Web服务的 基于注解的API。本质上,注解类和方法的信息能让运行时(Runtime)将它们暴露为资源,这种方法和通过Servlet编程模型来暴露类与方法的做 法有很大区别。实现JAX-RS的运行时(Runtime)周旋于HTTP协议和Java类之间,考虑URI、被请求和被接受的内容类型和HTTP方法。

 

    如果将Web看成是服务,那RESTful Web服务的Java规范就是以web services的角度来看待Web。又要经过资源与服务的辨析,在Fielding博士的论文里,有几个地方描述了资源:

 

写道
表5-1 REST的数据元素
数据元素                           现代Web实例
   资源             一个超文本引用意图指向的概念上的目标

 

写道
任何能够被命名的信息都能够作为一个资源 。一个资源是 到一组实体的概念 上的映射 ,而不是在任何特定时刻与该映射相关联的实体本身。

 

写道
6.2 将REST应用于URI
6.2.1 重新定义资源

存在着很多地址对应于一个服务,而不是一个文档 ——创作者可能是有意将读者引导到那个服务,而不是引导到来自预先访问那个服务而获取到的特定的结果。

    这与早期的对于资源的定义有了不同,过去资源就是指实体,而现在资源是抽象概念,是概念上的映射,是表示一种语义。

    写道

REST达到了这个目标,通过将一个资源定义为创作者想要标识的语义,而不是对应于创建这个引用时的那些语义的值。然后留给创作者来保证所选择的这个标识符确实真正标识出了他所想要表达的语义。
写道
将“资源”定义为一个URI标识了一个概念,而不是标识了一个文档。

 

 

写道
资源 是一种概念 上的映射 ——服务器接收到标识符(标识这个映射),将它应用于当前的映射实现(mapping implementation,通常是与特定集合相关的树的深度遍历和/或哈希表的组合)上,以发现当前负责处理该资源的处理器实现,然后处理器实现基于请求的内容选择适当的动作+响应。

 

    这一句离我们日常开发上的用语最为接近,我马上想到的是Struts,Spring MVC之类的控制器模型,尤其是控制器映射。URL或者URN是资源标识符的现代Web实例,比如sslaowan最新的日志:www.iteye.com/blog/lasted-post,它标识了一个资源,就是sslaowan最新的日志,而这个资源是一种概念上的映射,它将对应于一个映射实现,这个映射实现是运行时中的一个哈希Map,它可能来自于XML映射文件,数据库表或者是注解,通过这个Key/Value数据结构找到对应的处理器(也可以叫控制器【见Spring Reference】)实现。

    这和我们用Servlet这样的Java API感觉上是类似的,根据Mapping,可以转向一个具体的文件,或者是转向一个处理器来返回一个响应 (其中可能包含一个表述)  。

    那么既然Servlet这样的Java API都是这样做的,跟现在Spring3支持的注解方式的REST,以及CXF、RestEasy这样支持规范的框架,究竟有什么不同或者说是进步呢?

    先看看Struts1.2怎么做映射:

 

 <action-mappings>
     <action path="/getPost" 
                type="org.sample.fourm.GetPostAction"  scope="request"  >    
       <action path="/blog/edit" 
                name="post"
                type="org.sample.fourm.PostEditAction"  scope="request">    
</action>

   我们可能会这样写URL:www.iteye.com/getPost.do?id=123获得某个用户的blog列表。然后会使用URL:www.iteye.com/blog/edit.do?id=12334,获得要修改的日志。

   由于人们觉得应该将一个功能写在一个Action里,因此使用DispatchAction,加入parameter="method" 在<action path>段中即可。然后通过method=edit|new|list等来实现上述功能。

   Spring的做法类似,可以参见http://www.iteye.com/topic/72195

 

<bean id="urlMapping" class="org.springframework.web.servlet.handler.SimpleUrlHandlerMapping">       
        <property name="mappings">       
            <props>       
                <prop key="/getPost">GetPostAction</prop>       
            </props>       
        </property>       
 </bean>   

    我们可以通过通配符来使这件事变得更容易,然后Spring把这件事又推进了一步,利用CoC,只要按照“惯例”来写,就无需配置映射了。实际上Rails给出一个缺省的Router原理类似。

    之后我们做的事情就是利用HTML支持的Get和POST方法做所有的事情,一种是用Get方式,URL后面有一个用&分隔的请求变量串;一种是通过POST方式,将请求变量放到HTTP体里。Struts和Spring都采用FrontController模式来处理请求,根据映射(ActionMapping或HandlerMapping)来找到相应的处理器或者直接找到文件。

    下面对比几个URI:

   1 www.iteye.com/blog/123和www.iteye.com/getPost.do?id=123和www.iteye.com/getPost.do?postId=123谁能更好的表示获得用户id为123的用户的日志这个语义.

   2  www.iteye.com/blog/123/edit和www.iteye.com/editPost.do?id=12334和www.iteye.com/blog/edit?id=12334和www.iteye.com/editPost.do?postId=12334和www.iteye.com/blog/getPostForEdit/12234(有点像SQL里的select for update)谁能更好的表示获得Post编号为12234的Post并要对它进行修改这个语义?

    RoR的标准做法显然是把Blog看成是资源,然后将其他表示请求语义的内容加入到资源标志中,或者是放入到表述中,比如lock(锁定帖子)。

    过去的框架都没法做/blog/{userId},/blog/{postId}/edit,或者是/blog/{userId}/post/{date-period}/list这样的映射。现在可以了,关键就是URL模板和参数映射:

    Spring 3代码

 

@RequestMapping(value="/blog/{userId}/posts/{date-period}/list", method=RequestMethod.GET)
public String getPost(@PathVariable("userId") long userId, @PathVariable("date-period") String datePeriod, Model model) {
 
}

   关键问题是,有必要这样做吗?

 

 

   下面看看REST API和RPC的不同:

   Fielding博士对于REST的网络API的定义,即连接器接口的描述如下:

 

写道
连接器接口与过程调用有些类似,但是在参数和结果的传递方式上有着重要的区别。其传入参数 由请求的控制数据、一个表示请求的目标的资源标识符、以及一个可选的表述组成。其传出参数 由响应的控制数据、可选的资源元数据、以及一个可选的表述组成。

   写成API的形式如下:

public [响应的控制数据|[资源元数据]|[表述]] 连接器接口 (请求的控制数据 data,资源标识符 id,[表述] p)
 

 

    其中控制数据 对应的现代Web实例是:if-modified-since(如果包含了 GET 请求,导致该请求条件性地依赖于资源上次修改日期。 如果出现了此头标,并且自指定日期以来,此资源已被修改,应该反回一个 304 响应代码。 )、cache-control(一个用于定义缓存指令的通用头标。)

    表述 包括表述的数据(比如HTML文档,JPEG图片等)和表述的元数据(如媒体类型、最后修改时间)。其中媒体类型就是text/html,image/jpeg之类的。

    资源的元数据 对应的现代Web实例是源链接、alternates、vary(一个响应头标,用于表示使用服务器驱动的协商从可用的响应表示中选择响应实体。)在Fielding博士的论文中特意将内容协商作为了一节:

 

写道
抢先式(服务器驱动(server-driven)的)协商发生在以下情况:当服务器根据请求头
信息字段的值或正常的请求参数(方法/标识符/状态码)之外的某事物,为某种特殊的请求
方法/标识符/状态码的组合改变响应的表述。当这种情况发生时,客户端需要得到通知,这
样当语义透明时一个缓存就能够知道,要为将来的请求使用一个特殊的已缓存响应,而一个
用户代理一旦知道协商的信息对于接收到的响应的影响,就能够提供比正常情况下发送的更
加详细的首选项。HTTP/1.1为这个目的引入了Vary头信息字段。Vary简单地列出了请求头
信息字段的维度(译者注:即可以进行协商的头信息字段的列表),这样响应就能够根据这
些信息发生改变。

 

    另外一个更接近我们日常开发使用的术语的描述:

 

写道
所有资源 都会将一个请求 (由方法、标识符、请求头信息和有时存在的一个表述组成)
映射到一个响应 (由一个状态码、响应头信息字段和有时存在的一个表述组成)。

 

 

 

4
1
分享到:
评论

相关推荐

    spring3.0帮助文档(包含REST资料)

    ◆全面的REST支持:在Spring MVC中天然支持REST,如REST式的请求映射,URI变量提取等。 ◆富Portlet 2.0支持:Spring MVC完全支持Portlet 2.0环境以及Portlet 2.0中新的事件与资源请求模型。 ◆对象/XML映射(OXM...

    spring加载restful(文档+程序源码)

     在Spring框架支持REST之前,人们会使用其他几种实现技术来创建Java RESTful Web Services,如Restlet、RestEasy和Jersey。Jersey是其中最值得注意的,它是JAX-RS(JSR 311)的参考实现。  Spring是一个得到广泛...

    rest-api-study:对象关系映射(ORM),模式设计,数据库迁移,测试REST API,身份访问管理(IAM),安全REST API,服务器部署,CICD管道,自动化测试,容器化等

    使用Flask,SQLAlchemy的后端API示例概述该项目的目的是学习如何构建数据库支持的API和Web应用程序,包括REST API,架构设计,数据库迁移,对象关系映射(ORM),API测试,使用Json Web令牌(JWT)进行身份验证和...

    restlet-jse-2.1.1.zip

    Restlet项目为“建立REST概念与Java类之间的映射”提供了一个轻量级而全面的框架。它可用于实现任何种类的REST式系统,而不仅仅是REST式Web服务;而且,事实证明它自从2005年诞生之时起,就是一个可靠的软件。 ...

    go-restful:使用Go构建REST风格的Web服务的软件包

    这项基本的REST设计原则在创建,读取,更新和删除(CRUD)操作与HTTP方法之间建立了一对一的映射。 根据此映射: GET =检索资源的表示形式 POST =如果要使用服务器端算法将内容发送到服务器以创建指定资源集合的...

    ASP EXCEL导入SQL

    在Rails框架的充分利用了REST软件架构之后,人们更加坚信REST的重要性和必要性。Rails利用REST软件架构思想对网络服务也提供了一流的支持。从最直观的角度看待REST,它是网络服务最理想的手段,但是Rails框架把REST...

    spring + cxf + restful + soap 集成小项目

    URIpath参数是从请求的URI中抽取的,而且参数的名称和@Path注解中定义的变量名对应。 @QueryParam注解是可以抽取并在资源类中使用的一类参数。Query参数是从请求URI的查询参数中抽取的。 @Consumes注解是用来指定...

    identifier_translation_service:HIRMEOS WP6的通用服务,允许从标准URI转换为标准URI。

    翻译服务将作品(出版物)映射到URI(例如info:doi:10.11647 / obp.0001,urn:isbn:9781906924010, ://www.openbookpublishers.com/product/3),以允许从一个标识符转换为另一个标识符。建立认证方式如果您...

    sepomex:SEPOMEX数据库的REST API

    Sepomex是一个REST API,可映射墨西哥当前邮政编码中的所有数据。 您可以从获取CSV或Excel文件 我们构建此API的目的是为开发人员提供一种查询全国邮政编码,州和城市的方法。 目录 快速开始 开始使用JSON响应的基本...

    host-rules-editor:呈现主机规则映射的元素

    ARC的主机规则允许为请求引擎创建内部映射,以更改连接URI,并保留原始Host标头。 这允许测试服务器上的虚拟主机配置。 发出请求时,将对规则进行依次评估以产生最终请求URL。 这允许定义适用于先前评估的URL的多个...

    restlet-jee-2.1.1.zip

    Restlet项目为“建立REST概念与Java类之间的映射”提供了一个轻量级而全面的框架。它可用于实现任何种类的REST式系统,而不仅仅是REST式Web服务;而且,事实证明它自从2005年诞生之时起,就是一个可靠的软件。 ...

    question-answer-api:问题 - 回答 Rest Api - ExpressJs - MongoDB

    问答 API入门要让 Node 服务器在本地运行: 克隆这个 repo npm install安装所有必需的依赖项创建 MongoDb 集群并获取连接 MongoDb URI 在./config/env下的config.env设置环境...JWT - 用于将 MongoDB 数据建模和映射

    django-vs-spring

    安全框架基于ACL模板框架缓存框架表单验证框架URL 映射(干净的 URL、RESTful URI) 是的是的HTML5 ? ? REST(将数据公开为 RESTful Web 服务) 是的是的移动支持? ? 脚手架工具不(?) 春之谷似乎也有一些用于 ...

    map:用于“侦察”协作映射引擎的实验性 AngularJS 前端

    cd 地图/脚本/ ./coffee_watch.sh cp config.js.sample config.js 纳米配置.js 配置 = { templateBaseUrl: '/views/', bucket_uri: ' ', useHtml5Mode: false, media_uri: ' ', rest_uri: " " } 光盘.. cd 风格/ ...

    restws_schema:帮助RESTful Web服务服务于任意架构,而不是Drupal的实体架构

    例子: URI:RESOURCE / ID.json 对象密钥在规范中定义,包括: id:当前资源对象的ID 引用(包括相应的引用)是entityreference字段,并且包含: uri:引用的资源对象REST URI 资源:引用的资源名称id:引用的资源...

    play框架手册

    关于REST - 14 - routes文件语法 - 14 - HTTP方法 - 15 - URI范示 Pattern - 15 - Java调用定义 - 17 - 把404当作action来用 - 17 - 指派静态参数 - 17 - 变量和脚本 - 18 - 路由优先级 - 18 - 服务器静态资源 - 18 ...

    android-restlet:一个非常简单的ptojecttutorial,显示如何在Android下使用Restlet和Gson库

    android-restlet 一个非常简单的... -&gt; restlet.sdk ———&gt;实体———&gt; http —————&gt;客户—————&gt;资源———&gt;接口———&gt;大事记———&gt;泛型restlet.sdk.entities 包含所有类以映射REST资源的JSON项restlet.sdk.

    ioBroker.ETA

    因此,我建议使用以下JS实现-您只需从ETA设备映射一次正确的URI。 var http = require('http'); var xpath = require('xpath'); var dom = require('xmldom').DOMParser; var etaIP = '...

    go web编程

    1.7 URI 15 1.8 HTTP/2简介 16 1.9 Web应用的各个组成部分 16 1.9.1 处理器 17 1.9.2 模板引擎 18 1.10 Hello Go 18 1.11 小结 21 第2章 ChitChat论坛 23 2.1 ChitChat简介 23 2.2 ...

    看板

    database →如何考虑将数据库架构映射到REST API? 应该更多地考虑前端将要请求什么/用户将如何使用该应用程序? 我是否需要为每个表进行CRUD操作的路由? 数据库→这是合法的URI:postgres:// $ {user}:$ {...

Global site tag (gtag.js) - Google Analytics