Spring MVC_REST
一、REST 简介
1、概念
Representational State Transfer——表现层(资源)状态转化。是目前最流行的一种互联网软件架构风格。
它倡导结构清晰、符合标准、易于理解、扩展方便的 Web 架构体系,主张严格按照 HTTP 协议中定义的规范设计结构严谨的 Web 应用架构体系。由于 REST 所倡导的理念让 Web 应用更易于开发和维护,更加优雅简洁,所以正得到越来越多网站的采用。
资源(Resources):网络上的一个实体,或者说是网络上的一个具体信息。它可以是一段文本、一张图片、一首歌曲、一种服务,总之就是一个具体的存在。可以用一个 URI(统一资源定位符)指向它,每种资源对应一个特定的 URI 。要获取这个资源,访问它的 URI 就可以,因此 URI 即为每一个资源的独一无二的识别符。
表现层(Representation):把资源具体呈现出来的形式,叫做它的表现层(Representation)。比如,文本可以用 txt 格式表现,也可以用 HTML 格式、XML 格式、JSON 格式表现,甚至可以采用二进制格式。
状态转化(State Transfer):每发出一个请求,就代表了客户端和服务器的一次交互过程。HTTP 协议,是一个无状态协议,即所有的状态都保存在服务器端。因此,如果客户端想要操作服务器,必须通过某种手段,让服务器端发生“状态转化”(State Transfer)。而这种转化是建立在表现层之上的,所以就是 “表现层状态转化”。具体说,就是 HTTP 协议里面,四个表示操作方式的动词:GET、POST、PUT、DELETE。它们分别对应四种基本操作:GET 用来获取资源,POST 用来新建资源,PUT 用来更新资源,DELETE 用来删除资源。
请求方式 | 作用 |
---|---|
GET | 查询 |
POST | 保存 |
PUT | 更新 |
DELETE | 删除 |
2.REST 风格的 URL
REST 风格要求我们不要再使用问号键值对的方式携带请求参数,而是从 URL 地址中获取。下面我们进行一下对比:
① 保存操作
URL | 请求方式 | |
---|---|---|
TRADITIONAL URL | http://localhost:8080/CRUD/saveEmp | POST 请求 |
RESTFUL URL | http://localhost:8080/CRUD/emp | POST请求 |
② 删除操作
URL | 请求方式 | |
---|---|---|
TRADITIONAL URL | http://localhost:8080/CRUD/removeEmp?empId=2 | GET 请求 |
RESTFUL URL | http://localhost:8080/CRUD/emp/2 | DELETE请求 |
③ 更新操作
URL | 请求方式 | |
---|---|---|
TRADITIONAL URL | http://localhost:8080/CRUD/updateEmp | POST 请求 |
RESTFUL URL | http://localhost:8080/CRUD/emp | PUT请求 |
④ 查询操作(查询单个对象)
URL | 请求方式 | |
---|---|---|
TRADITIONAL URL | http://localhost:8080/CRUD/getEmp?empId=2 | GET 请求 |
RESTFUL URL | http://localhost:8080/CRUD/emp/2 | GET请求 |
3、REST 风格 URL 的好处
① 含蓄,安全
使用问号键值对的方式给服务器传递数据太明显,容易被人利用来对系统进行破坏。使用 REST 风格携带数据不再需要明显的暴露数据的名称。
② 风格统一
URL 地址整体格式统一,从前到后始终都使用斜杠划分各个内容部分,用简单一致的格式表达语义。
③ 无状态
在调用一个接口(访问、操作资源)的时候,可以不用考虑上下文,不用考虑当前状态,极大的降低了系统设计的复杂度。
④ 严谨,规范
严格按照 HTTP1.1 协议中定义的请求方式本身的语义进行操作。
⑤ 简洁,优雅
过去做增删改查操作需要设计 4 个不同的 URL,现在一个就够了
传统风格 | REST 风格 | |
---|---|---|
URL | 请求方式 | |
/CRUD/saveEmp | /CRUD/emp | POST |
/CRUD/removeEmp?empId=2 | /CRUD/emp/2 | DELETE |
/CRUD/updateEmp | /CRUD/emp | PUT |
/CRUD/editEmp?empId=2 | /CRUD/emp/2 | GET |
⑥ 丰富的语义
通过 URL 地址就可以知道资源之间的关系。
http://localhost:8080/shop
http://localhost:8080/shop/product
http://localhost:8080/shop/product/cellPhone
http://localhost:8080/shop/product/cellPhone/iPhone
二、SpringMVC 对四种请求方式的支持
1、说明
受 HTML 的限制,只有 GET 请求和 POST 请求是可以直接生成的。
为了生成 PUT 和 DELETE 请求方式我们需要借助一个过滤器:
org.springframework.web.filter.HiddenHttpMethodFilter
这个过滤器可以将 POST 请求转换为 PUT 或 DELETE 等其他形式。
2、HiddenHttpMethodFilter 的使用方法
① 在 web.xml 中进行配置,拦截所有资源。
1 | <filter> |
② 在表单隐藏域中通过_method 请求参数附带请求方式名称
1 | <!-- 将POST请求转为PUT请求 --> |
③ 通过点击超链接执行删除操作。
这是一个难点,超链接中没有表单隐藏域,所以需要将超链接转换为表单进行提交,这就需要借助于 JavaScript。
3、删除超链接转为 DELETE 请求
① 方案一:把超链接改成表单
1 | <a href="${pageContext.request.contextPath}/removeEmp?empId=${employee.empId}" |
修改后:
1 | <form action="${pageContext.request.contextPath}/removeEmp" method="post"> |
② 方案二:还是基于超链接修改
[1]提供一个通用的表单
1 | <!-- 1、提供一个通用的表单,用来将GET请求先转换为POST,然后再发送_method请求参数 --> |
[2]加入 jQuery 环境
1 | <script |
[3]编辑 jQuery 代码
1 | $(function () { |
[4]后端 handler 方法
1 |
|
4、@PathVariable 注解
① 工作机制
[1]URL 地址举例
/get/emp/2
[2]使用方式
@RequestMapping 注解中,使用一对儿大括号把 URL 地址中动态、会变的部分给标记出来
在大括号中给这个变量起个名字
在 handler 方法形参位置使用@PathVariable 注解引用这个名字
@PathVariable 注解修饰方法的一个形参
SpringMVC 会把 URL 地址中匹配出来的具体值从形参这里传入
② 代码举例
[1]一个参数的情况
HTML 代码:
1 | <a href="${pageContext.request.contextPath}/get/emp/1">一个参数情况</a><br /> |
Java 代码:
1 |
|
[2]多个参数的情况
HTML 代码:
1 | <a href="${pageContext.request.contextPath}/send/message/tom/tell/jerry" |
Java 代码:
1 | // /send/message/tom/tell/jerry |
5、实际请求方式和要求请求方式不一致:405 错误
实际请求方式:DELETE
要求请求方式:PUT
1 |
其他典型错误响应状态码:
400:往往是请求参数导致的错误
403:表示访问目标资源没有权限
404:表示访问不到目标资源
- URL 地址确实不对
- Web 应用启动时控制台已经抛出异常,导致整个 Web 应用不可用,访问任何资源都是 404
- 访问了 WEB-INF 目录下的资源
- DispatcherServlet 的 url-pattern 配置的是/*
- 服务器端按照旧代码运行,需要清理、重新部署
405:请求方式不匹配
406:实际请求的 URL 地址扩展名是 html,但是服务器端即将返回 JSON 格式的数据,『挂羊头,卖狗肉』