一、REST 的基础知识

我敢打赌这并不是你第一次听到或读到REST这个词。当讨论REST时,有一种常见的错误就是将其视为“基于URL的Web服务”—— 将REST作为另一种类型的RPC机制,只不过是通过简单的HTTP URL来触发。恰好相反,REST 和 RPC 几乎没有任何关系。RPC 是面向服务的,并关注于行为和动作;而REST 是面向资源的,强调描述应用程序的事物和名词。

REST(Representational State Transfer)表述性状态转移,已信息为中心,为了理解REST是什么,我们将它的首字母缩写拆分为不同的构成部分:

表述性(Representational):REST资源实际上可以用各种形式来进行表述,包括XML、JSON(JavaScript Object Notation)甚至HTML——最适合资源使用者的任意形式;
状态(State):当使用REST的时候,我们更关注资源的状态而不是对资源采取的行为;
转移(Transfer):REST涉及到转移资源数据,它以某种表述性形式从一个应用转移到另一个应用。

更简洁地讲,REST就是将资源的状态以最适合客户端或服务端的形式从服务器端转移到客户端(或者反过来)。其实就是,比如我想要 application/json 格式的数据,REST服务就能为我提供JSON格式的数据;我想要 application/xml 格式的数据,REST服务就能为了提供XML格式的数据(或者反过来)。

在REST中,资源通过URL进行识别和定位。至于RESTful URL的结构并没有严格的限制,但是URL应该能够识别资源,而不是简单的发一条命名到服务器上:

Create:POST
Read:GET
Update:PUT或PATCH
Delete:DELETE

tips:实际上,POST请求非幂等性的特点使其成为一个非常灵活的方法,对于无法适应其他HTTP方法的语义的操作,它都能胜任。

二、Spring MVC 构建 REST API

Spring 对 REST 提供了良好的支持,支持以下方式来创建 REST 资源:

  • 控制器可以处理所有的HTTP方法,包含四个主要的REST方法:GET、PUT、DELETE以及POST。
  • 消息转换器(Message conversion)将资源的Java表述形式转换为发送给客户端的表述形式。
  • 借助于 SpringMVC 的一系列注解,构建 REST API
  • 借助 RestTemplate,Spring应用能够方便地使用REST资源。

1、消息转换器(Message conversion)

消息转换(message conversion)提供了一种更为直接的方式,它能够将控制器产生的数据转换为服务于客户端的表述形式。当使用消息转换功能时,DispatcherServlet不再需要那么麻烦地将模型数据传送到视图中。实际上,这里根本就没有模型,也没有视图,只有控制器产生的数据,以及消息转换器(message converter)转换数据之后所产生的资源表述。

Spring 自带了各种各样的转换器,如下使用了 MappingJackson2HttpMessageConverter,并由它转换为返回客户端的JSON表述形式。

    <mvc:annotation-driven>
<!--使用HTTP信息转换器-->
<mvc:message-converters>
<!--读取或写入Resource-->
<bean class="org.springframework.http.converter.ResourceHttpMessageConverter"/>
<!--在JSON和类型化的对象或非类型化的HashMap间互相读取和写入-->
<bean class="org.springframework.http.converter.json.MappingJackson2HttpMessageConverter">
<!--服务端支持返回的资源形式-->
<property name="supportedMediaTypes">
<list>
<value>text/html;charset=UTF-8</value>
<value>application/json;charset=UTF-8</value>
</list>
</property>
</bean>
</mvc:message-converters>
</mvc:annotation-driven>

2、SpringMVC 的 REST 注解

@PathVariable:控制器能够处理参数化的URL(将变量输入作为URL的一部分);
@ResponseBody:告诉Spring跳过正常的模型/视图流程,并使用消息转换器。它将会告知Spring,我们将要返回的对象作为资源发送给客户端,并将其转换为客户端可接受的形式。
@RequestBody:告诉Spring查找一个消息转换器,将来自客户端的资源表述转换为对象。
@RestController:如果在控制器类上使用@RestController来代替@Controller的话,Spring将会为该控制器的所有处理方法应用消息转换功能。我们不必为每个方法都添加@ResponseBody了。
@ResponseStatus:指定返回的状态码。
@ResponseEntity:作为@ResponseBody的替代方案,控制器方法可以返回一个ResponseEntity对象。ResponseEntity中可以包含响应相关的元数据(如头部信息和状态码)以及要转换成资源表述的对象。

    @RequestMapping(
value = "listUserDTO"
, method = RequestMethod.POST
, consumes = "application/json")
public ResponseEntity<UserDTO> saveUserDto(@RequestBody UserDTO userDTO, UriComponentsBuilder ucb) {
UserDTO user = userService.saveUser(userDTO);
HttpHeaders headers = new HttpHeaders();
URI uri = ucb.path("/").path(user.getName()).build().toUri();
headers.setLocation(uri);
ResponseEntity<UserDTO> userDTOResponseEntity = new ResponseEntity<>(user, headers, HttpStatus.CREATED);
return userDTOResponseEntity;
}

三、RestTemplate API

RestTemplate 定义了36种与REST资源交互的形式(其实只有11个独立的方法,10个被重载了3次,另外一个被重载了6次),其中大多数都对应于HTTP的方法。大多数HTTP方法都以三种方法进行了重载:

# 1. 一个使用String作为URL格式,并使用可变参数列表指明URL参数。
# url 参数指定访问的地址, responseType 参数定义该方法的返回类型, urlVariables 参数为 url 中占位符对应的参数。
getForObject (String url, Class responseType, Object... urlVariables): # 2. 一个使用String作为URL格式,并使用Map指明URL参数。
#在该函数中,使用 Map 类型的 urlVariables 替代上面数组形式的 urlVariables,因此使用时在 url 中需要将占位符的名称与 Map 类型中的 key一一对应设置。
getForObject(String url, Class responseType, Map urlVariables): # 3. 一个使用 java.net.URL 作为 URL格式,不支持参数化URL;
# 使用 URI 对象来替代之前的 url和urlVariables 参数使用。
getForObject(URI url, Class responseType)

RestTemplate定义了11个独立的操作,而每一个都有重载,这样一共是36个方法 :

-- postForEntity() :POST数据到一个URL,返回包含一个对象的ResponseEntity,这个对象是从响应体中映射得到的。
-- postForLocation() :POST数据到一个URL,返回新创建资源的URL。
-- postForObject() :POST数据到一个URL,返回根据响应体匹配形成的对象。

# 需要注意的是新增加的 request 参数,该参数可以是一个普通对象,也可以是一个 HttpEntity 对象。
# 如果是一个普通对象,而非 HttpEntity 对象的时候,RestTemplate会将请求对象转换为一个 HttpEntity 对象来处理,其中 Object 就是 request的类型,request内容会被视作完整的body来处理;
# 如果 request 是一个HttpEntity对象,那么就会被当作一个完成的 HTTP 请求对象来处理,这个 request 中不仅包含了 body 的内容, 也包含了 header 的内容。
postForObject(String url, Object request, Class responseType, Map uriVariables)

-- delete() :在特定的URL上对资源执行HTTP DELETE操作。
-- put() :PUT资源到特定的URL。
-- getForEntity() :发送一个HTTP GET请求,返回的ResponseEntity包含了响应体所映射成的对象。
-- getForObject() :发送一个HTTP GET请求,返回的请求体将映射为一个对象。
-- headForHeaders() :发送HTTP HEAD请求,返回包含特定资源URL的HTTP头。
-- optionsForAllow() :发送HTTP OPTIONS请求,返回对特定URL的Allow头信息。
-- exchange() :在URL上执行特定的HTTP方法,返回包含对象的ResponseEntity,这个对象是从响应体中映射得到的。
-- execute() :在URL上执行特定的HTTP方法,返回一个从响应体映射得到的对象。

RestTemplate 的相关操作以及如何使用 SpringMVC创建REST端点可参考:https://github.com/JMCuixy/SpringMvcForRest

SpringMVC 与 REST.的更多相关文章

  1. 【分享】标准springMVC+mybatis项目maven搭建最精简教程

    文章由来:公司有个实习同学需要做毕业设计,不会搭建环境,我就代劳了,顺便分享给刚入门的小伙伴,我是自学的JAVA,所以我懂的.... (大图直接观看显示很模糊,请在图片上点击右键然后在新窗口打开看) ...

  2. Springmvc数据校验

    步骤一:导入四个jar包 <?xml version="1.0" encoding="UTF-8"?> <beans xmlns=" ...

  3. 为什么做java的web开发我们会使用struts2,springMVC和spring这样的框架?

    今年我一直在思考web开发里的前后端分离的问题,到了现在也颇有点心得了,随着这个问题的深入,再加以现在公司很多web项目的控制层的技术框架由struts2迁移到springMVC,我突然有了一个新的疑 ...

  4. 【SSM框架】Spring + Springmvc + Mybatis 基本框架搭建集成教程

    本文将讲解SSM框架的基本搭建集成,并有一个简单demo案例 说明:1.本文暂未使用maven集成,jar包需要手动导入. 2.本文为基础教程,大神切勿见笑. 3.如果对您学习有帮助,欢迎各种转载,注 ...

  5. 快速搭建springmvc+spring data jpa工程

    一.前言 这里简单讲述一下如何快速使用springmvc和spring data jpa搭建后台开发工程,并提供了一个简单的demo作为参考. 二.创建maven工程 http://www.cnblo ...

  6. redis集成到Springmvc中及使用实例

    redis是现在主流的缓存工具了,因为使用简单.高效且对服务器要求较小,用于大数据量下的缓存 spring也提供了对redis的支持: org.springframework.data.redis.c ...

  7. 流程开发Activiti 与SpringMVC整合实例

    流程(Activiti) 流程是完成一系列有序动作的概述.每一个节点动作的结果将对后面的具体操作步骤产生影响.信息化系统中流程的功能完全等同于纸上办公的层级审批,尤其在oa系统中各类电子流提现较为明显 ...

  8. springMVC学习笔记--知识点总结1

    以下是学习springmvc框架时的笔记整理: 结果跳转方式 1.设置ModelAndView,根据view的名称,和视图渲染器跳转到指定的页面. 比如jsp的视图渲染器是如下配置的: <!-- ...

  9. springMVC初探--环境搭建和第一个HelloWorld简单项目

    注:此篇为学习springMVC时,做的笔记整理. MVC框架要做哪些事情? a,将url映射到java类,或者java类的方法上 b,封装用户提交的数据 c,处理请求->调用相关的业务处理—& ...

  10. springmvc的拦截器

    什么是拦截器                                                         java里的拦截器是动态拦截action调用的对象.它提供了一种机制可以使 ...

随机推荐

  1. 通过URL触发Jenkins构建

    用Jenkins做持续集成时,一般会使用webhooks触发构建,或者定时构建,这里记录用URL的方式触发Jenkins构建. Note: This assumes you're using Jenk ...

  2. Windows反复重启的可能的解决办法

    Windows反复重启,原因很多,下面提供两个可能的解决办法: 1. 查看BIOS中关于SATA的设置,一般只有两种PCIE和IDE,调整成另外一个试试: 2. 查看BIOS的启动模式,如果是UEFI ...

  3. MVC详解

    模型-视图-控制器(Modal View Controler,MVC)是Xerox PARC在八十年代为编程语言Smalltalk-80发明的一种软件设计模式,至今已被广泛使用.最近几年被推荐为Sun ...

  4. 为什么使用 Spring Boot?

    Spring 是一个非常流行的基于Java语言的开发框架,此框架用来构建web和企业应用程序.与许多其他仅关注一个领域的框架不同,Spring框架提供了广泛的功能,通过其组合项目满足现代业务需求. S ...

  5. Javascript高级编程学习笔记(73)—— 表单(1)表单基础

    表单 JS最初的一个用途就是帮助服务器分担处理表单的责任 时至今日,虽然web应用以及JS都有了长足的发展,但是表单依然是现在web应用中比较重要的部分. 因为默认的表单控件很丑,所以有时候我们会使用 ...

  6. Java核心技术卷一基础知识-第12章-泛型程序设计-读书笔记

    第12章 泛型程序设计 本章内容: * 为什么要使用泛型程序设计 * 定义简单泛型类 * 泛型方法 * 类型变量的限定 * 泛型代码和虚拟机 * 约束与局限性 * 泛型类型的继承规则 * 通配符类型 ...

  7. 第35节:Java面向对象中的多线程

    Java面向对象中的多线程 多线程 在Java面向对象中的多线程中,要理解多线程的知识点,首先要掌握什么是进程,什么是线程?为什么有多线程呢?多线程存在的意义有什么什么呢?线程的创建方式又有哪些?以及 ...

  8. Kali学习笔记7:三层发现

    三层发现:发送ICMP/IP数据包探测 第一种方式: 就是很简单的Ping命令: 不过linux的ping命令和windows的ping命令不一样,它会默认不停止地发数据包 我们可以通过-c参数来设置 ...

  9. 剑指offer【03】- 从尾到头打印链表(4种实现方法)

    题目:从尾到头打印链表 考点:链表 题目描述:输入一个链表,按链表值从尾到头的顺序返回一个ArrayList. 法一:ArrayList头插法 /** * public class ListNode ...

  10. freemarker常见语法大全,灰常有用!

    由于公司前端使用的技术是freemarker,于是没事就在网上看看别人写的关于freemarker的文章,感觉freemarker灰常简单,比jsp好用,jsp太乱太臃肿了,另外推荐大家看看freem ...