[转] 使用Spring MVC构建REST风格WEB应用

时间:2023-01-18 14:06:22

原文地址: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&period;X&lpar;三&rpar;:使用 Spring MVC &plus; MyBatis &plus; 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&period;0 RESTful Web Services and AngularJS

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

  8. 基于Spring &plus; Spring MVC &plus; Mybatis &plus; shiro 高性能web构建

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

  9. 【Spring学习笔记-MVC-18&period;1】Spring MVC实现RESTful风格-同一资源&comma;多种展现&colon;xml-json-html

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

随机推荐

  1. android adb命令

    adb查看logcat adb logcat <TAG>:* *:S 查看指定TAG的Log adb查看最上层activity:linux: adb shell dumpsys activ ...

  2. android 中IntentService的作用及使用

    IntentService是继承于Service并处理异步请求的一个类,在IntentService内有一个工作线程来处理耗时操作,启动IntentService的方式和启动传统Service一样,同 ...

  3. inverse理解

    首先术语inverse 被翻译为反转的意思.inverse 制定了关联关系中的方向. 当set的inverse属性默认情况下,hibernate会按照持久化对象的属性变化来同步更新数据库. 得到两条s ...

  4. Jplayer&lpar;转&rpar;

    Jplayer必须要加载 1.样式  jplayer.blue.monday.css 2.jq jquery.1.6.2.min.js 当前最新版本为1.6.2 3.jplayer的js jquery ...

  5. 支付返回post请求数据

    点击返回商家返回的post数据: {"requestBody":"singnType=&version=&businessId=00WGFKB20012& ...

  6. Trafic control 大框图&lpar;HTB &rpar;

    10.1. General diagram Below is a general diagram of the relationships of the components of a classfu ...

  7. Struts2 四、Struts2 处理流程

    1. 一个请求在Struts2框架中的处理步骤: a) 客户端初始化一个指向Servlet容器的请求: b) 根据Web.xml配置,请求首先经过ActionContextCleanUp过滤器,其为可 ...

  8. jQuery特效手风琴特效 手写手风琴网页特效

    今天写一个简单的手风琴效果,不用插件,利用强大的jQuery,写一个手风琴效果. 页面预览,请点击这里预览:  手风琴预览 案例分析: html结构 就是一个大盒子里面放着5个li,每个li的小小是2 ...

  9. 日志管理之 Docker logs - 每天5分钟玩转 Docker 容器技术(87)

    高效的监控和日志管理对保持生产系统持续稳定地运行以及排查问题至关重要. 在微服务架构中,由于容器的数量众多以及快速变化的特性使得记录日志和监控变得越来越重要.考虑到容器短暂和不固定的生命周期,当我们需 ...

  10. oracle表空间大小的限制和DB&lowbar;BLOCK&lowbar;SIZE的概念

    之前接触的项目表空间最大也不超过10G,所以导入数据库时一直使用导入本地的oracle数据库文件的方法,即根据dmp文件大小设置一个数据文件,设定表空间最大值. --创建表空间,数据文件为'F:\ap ...