原文地址:http://fancy888.iteye.com/blog/1629120

对于运行在网络上的MIS系统而言,处理数据的是整个系统的主要任务,翻开程序我们可以看到,80%以上的代码都在处理数据的CRUD操作。采用一种什么样的框架结构,能够使得处理数据的操作变得简单且易理解,这是大部分开发者尤其是架构设计者一直以来思考的一个问题。

REST(Representational State Transfer)是一种编程风格,特别是针对网络应用的设计和开发,采用REST可以显著降低开发的复杂性,提高系统的可伸缩性。

REST是一种独特的编程风格,与MVC强调的角色分层概念不同,REST强调使用统一的规则来规范对资源的操作,两者互为补充,相符相成,使用 MVC架构搭配REST编程风格构建基于网络的MIS系统将在不远的为未成为主流。本文着重介绍REST编程风格的核心规则,并且结合Spring MVC描述REST在实际应用中的代码形态。

使用REST风格开发WEB应用程序强调以下几点规则:

  1. 网络上的所有事物都被抽象为资源(resource);
  2. 每个资源对应一个唯一的资源标识(resource identifier);
  3. 通过通用的连接器接口(generic connector interface)对资源进行操作;
  4. 对资源的各种操作不会改变资源标识;
  5. 所有的操作都是无状态的(stateless)。

首先,在笔者看来,REST定义中的资源即应用程序所处理的数据。以订单管理系统为例,订单信息就是数据,同样客户信息和产品信息也是数据,在REST看来这些数据都是资源。

REST强调资源必须有具有唯一名称和ID,名称用来区分不同资源,ID用来定位同类资源中唯一的一条数据。在REST中,这些规则都是通过URI 来描述的。还是以上面的订单系统为例,我们将订单信息名称设定为order,客户信息为customer,货物信息为product,那么就存在几下的几 种URI设计:

  1. <!--标识所有的订单信息-->
  2. http://www.coolfancy.com/rest/order
  3. <!--标识所有的客户信息-->
  4. http://www.coolfancy.com/rest/customer
  5. <!--标识ID为1的货物信息-->
  6. http://www.coolfancy.com/rest/product/1

我们可以看出REST风格URI设计的特点:http://host/context/资源名称/[资源ID]。其中资源名称是必选项,资源ID可省略,省略资源ID用来标识一类资源的所有数据。

有了资源和用来标识资源的URI后,REST用连接器来标识对资源的操作。在这里,对资源的操作分为查询/获取、创建、删除、修改四种。在网络编程环境下,REST用HTTP协议作为连接器,用HTTP Method(请求方法)标识操作类型:

  • HTTP GET:查询和获取资源;
  • HTTP POST:创建资源;
  • HTTP PUT: 修改资源;
  • HTTP DELETE: 删除资源。

在完成资源和连接器两个核心概念的定义后,我们已经可以大体勾勒出REST风格编程的基本思路:

  1. 抽象和定义系统中的资源;
  2. 使用REST风格的URI将请求与资源进行绑定;
  3. 使用HTTP请求对资源进行操作;

还用上面提到的订单系统为例,请看下面的例子:

  1. <!--查询类别为服装的货物信息-->
  2. GET /rest/product HTTP/1.1
  3. Host: www.coolfancy.com
  4. productType 服装
  1. <!--查询ID为1的订单信息-->
  2. GET /rest/order/1 HTTP/1.1
  3. Host: www.coolfancy.com
  1. <!--删除ID为1的货物信息-->
  2. DELET /rest/product/1 HTTP/1.1
  3. Host: www.coolfancy.com
  1. <!--创建一条订单信息-->
  2. POST /rest/order HTTP/1.1
  3. Host: www.coolfancy.com
  4. field1 value1
  5. field2 value2
  6. ... ...

简单的说,URI加上HTTP METHOD构成了REST处理数据的核心规则:URI确定了操作的对象,HTTP METHOD则确定了操作的方式。

与传统处理数据的方式不同,如果不使用REST,那么操作的对象和操作方式将混合在URL设计中,正如首次提出REST概念的Roy T. Fielding博士所说的:“REST允许我们通过url设计系统”。事实上Roy也是Web协议的主要设计者,正是在他的参与下完成了HTTP1.1 规范的制定。

站在另一个角度,REST强调资源(数据)的概念,一切操作围绕特定资源展开,离开了资源,REST就失去了存在的意义。在这一点上,REST所倡导的思想与时下流行的Ajax的编程风格有着异曲同工之妙。

Ajax强调数据与展现分离,后台应用程序致力于生产数据,前台使用脚本进行数据的展示。对于数据的组织与传输Ajax并没有内置的支持。而 REST强调通过URI将请求与资源进行绑定,如果将REST与Ajax技术进行结合,则可以形成有效的互补,我们不妨将上面提到的编程思路进行扩展,仍 然以获取ID为1的订单信息为例:

  1. Ajax发起请求:http://www.coolfancy.com/rest/order/1;
  2. 通过REST风格的URI设计将请求与后台实体进行绑定;
  3. 后台实体返回包含产品信息的JSON/XML数据;
  4. 前台使用脚本进行数据的展示。

我们用Spring MVC来实现上面描述的过程,作为主流的MVC产品,Spring MVC天然支持REST编程风格,所以使用Spring MVC来搭建REST风格的应用程序将变得异常简单。

Spring MVC使用特殊的标注对Handler对象进行修饰,使得Handler能够处理REST风格的请求,我们来看几个例子:

  1. /**
  2. * 按ID值获取订单信息
  3. *
  4. * @param id
  5. * @return
  6. */
  7. @ResponseBody
  8. @RequestMapping(value = "/order/${id}", method = RequestMethod.GET)
  9. public OrderEntity getOrder(@PathVariable int id) {
  10. return orderManager.get(id);
  11. }
  12. /**
  13. * 按类型查询货物信息
  14. *
  15. * @param id
  16. * @return
  17. */
  18. @ResponseBody
  19. @RequestMapping(value = "/product", method = RequestMethod.GET)
  20. public List<ProductEntity> getProductByType(String type) {
  21. return productManager.queryByType(type);
  22. }
  23. /**
  24. * 创建订单信息
  25. *
  26. * @param id
  27. * @return
  28. */
  29. @RequestMapping(value = "/order", method = RequestMethod.POST)
  30. public void createOrder(OrderEntity entity) {
  31. orderManager.create(entity);
  32. }
  33. /**
  34. * 修改订单信息
  35. *
  36. * @param id
  37. * @return
  38. */
  39. @RequestMapping(value = "/order/${id}", method = RequestMethod.PUT)
  40. public OrderEntity updateOrder(@PathVariable int id, OrderEntity entity) {
  41. return orderManager.update(entity);
  42. }
  43. /**
  44. * 删除指定ID值的订单信息
  45. *
  46. * @param id
  47. * @return
  48. */
  49. @RequestMapping(value = "/order/${id}", method = RequestMethod.DELETE)
  50. public void deleteOrder(@PathVariable int id) {
  51. orderManager.delete(id);
  52. }

通过上面的例子可以看出,使用Spring MVC编写REST风格的应用程序是多么的简单。

需要我们注意的是,REST要求资源的标识是不变的,也就是说对于特定的资源,无论对这个资源作了什么样的操作,资源的ID不可以改变。之所以加入 这样的限制是为了保证URI的一致性。试想如果某个操作在处理过程中改变了资源的标识,那么为了保证规则的完整性,我们必须付出额外的代价去在其它的处理 中同步这些变化,这在REST中是不可接受的。

另一方面,REST要求针对资源的所有操作必须是无状态的,URI是确定资源的唯一途径。如果我们在处理数据的过程中融入了状态数据,那么针对同一资源的URI就会出现二义性,这将与REST的定义背道而驰。

[转] 使用Spring MVC构建REST风格WEB应用的更多相关文章

  1. 使用Spring MVC构建REST风格WEB应用

    转自:http://fancy888.iteye.com/blog/1629120 对于运行在网络上的MIS系统而言,处理数据的是整个系统的主要任务,翻开程序我们可以看到,80%以上的代码都在处理数据 ...

  2. spring mvc构建WEB应用程序入门例子

    在使用spring mvc 构建web应用程序之前,需要了解spring mvc 的请求过程是怎样的,然后记录下如何搭建一个超简单的spring mvc例子. 1) spring mvc的请求经历 请 ...

  3. 用Spring MVC开发简单的Web应用程序

    1 工具与环境 借助Eclipse4.3 + Maven3.0.3构建Java Web应用程序.使用Maven内置的servlet 容器jetty,不需手工集成Web服务器到Eclipse.还帮我们自 ...

  4. Spring Boot 2.X(三):使用 Spring MVC + MyBatis + Thymeleaf 开发 web 应用

    前言 Spring MVC 是构建在 Servlet API 上的原生框架,并从一开始就包含在 Spring 框架中.本文主要通过简述 Spring MVC 的架构及分析,并用 Spring Boot ...

  5. Spring Boot构建 RESTful 风格应用

    Spring Boot构建 RESTful 风格应用 1.Spring Boot构建 RESTful 风格应用 1.1 实战 1.1.1 创建工程 1.1.2 构建实体类 1.1.4 查询定制 1.1 ...

  6. 干净win7要做几步才能运行第一个Spring MVC 写的动态web程序

    干净win7要做几步才能运行第一个Spring MVC 写的动态web程序: 1. 下载安装jdk 2. 配置Java环境变量 3. 测试一下第1,2两步是否完全成功:http://jingyan.b ...

  7. CRUD using Spring MVC 4.0 RESTful Web Services and AngularJS

    国内私募机构九鼎控股打造APP,来就送 20元现金领取地址:http://jdb.jiudingcapital.com/phone.html内部邀请码:C8E245J (不写邀请码,没有现金送)国内私 ...

  8. 基于Spring + Spring MVC + Mybatis + shiro 高性能web构建

    一直想写这篇文章,前段时间 痴迷于JavaScript.NodeJs.AngularJS,做了大量的研究,对前后端交互有了更深层次的认识. 今天抽个时间写这篇文章,我有预感,这将是一篇很详细的文章,详 ...

  9. 【Spring学习笔记-MVC-18.1】Spring MVC实现RESTful风格-同一资源,多种展现:xml-json-html

    概要 要实现Restful风格,主要有两个方面要讲解,如下: 1. 同一个资源,如果需要返回不同的形式,如:json.xml等: 不推荐的做法: /user/getUserJson /user/get ...

随机推荐

  1. [转]ANDROID NOTIFICATIONS USING CORDOVA AND IONIC

    本文转自:http://intown.biz/2014/04/11/android-notifications/ ANDROID NOTIFICATIONS USING CORDOVA AND ION ...

  2. 【HTML】嵌入图像

    img元素允许我们在HTML文档里嵌入图像. 要嵌入一张图像需要使用src和alt属性,代码如下: <img src="../img/example/img-map.jpg" ...

  3. jdk8-日期

    今天遇到了日期问题,看了下jdk8新特性 http://www.ibm.com/developerworks/cn/java/j-lo-jdk8newfeature/index.html Java 的 ...

  4. C#小游戏(文字对战游戏)

    第一代,不是很完善,会在后续增加更多的功能 主: using System; using System.Collections.Generic; using System.Linq; using Sy ...

  5. vijos1431[noip2007]守望者的逃离(背包动规)

    描述 恶魔猎手尤迪安野心勃勃,他背叛了暗夜精灵,率领深藏在海底的娜迦族企图叛变.守望者 在与尤迪安的交锋中遭遇了围杀,被困在一个荒芜的大岛上.为了杀死守望者,尤迪安开始对这 个荒岛施咒,这座岛很快就会 ...

  6. chrome插件编写之新版hello world

    编写chrome插件之前,需要熟悉一下相应的chrome插件开发环境.从编写hello world开始,参考阅读官方的教程,是一个不错的选择.这里主要是基于chrome的官方教程,稍稍做了一些修改和扩 ...

  7. 加载cocos studio场景

    今天尝试加载cocos studio的场景. 新版的cocos studio中,"导出"选项变成了"发布".发布之后会生成一个res文件夹,其中每个场景有一个. ...

  8. 未找到数据,异常处理:exception when no_data_found then 异常处理语句;

    未找到数据. 在 select 字段 Into 变量 from 表 where 条件: 这种语句中很有可能会有select 不到数据的问题,导致报错"未找到数据" 要解决这种问题需 ...

  9. JavaScript 运算符

    JavaScript 运算符 JavaScript 运算符用于赋值,比较值,执行算术运算等. JavaScript 算术运算符 算术运算符用于执行两个变量或值的运算. 赋值 y = 5, 以下表格将向 ...

  10. BZOJ 2005: [Noi2010]能量采集

    2005: [Noi2010]能量采集 Time Limit: 10 Sec  Memory Limit: 552 MBSubmit: 3312  Solved: 1971[Submit][Statu ...