Hey, Nice to meet You. 

必有过人之节.人情有所不能忍者,匹夫见辱,拔剑而起,挺身而斗,此不足为勇也,天下有大勇者,猝然临之而不惊,无故加之而不怒.此其所挟持者甚大,而其志甚远也.          ☆☆☆所谓豪杰之士,

SpringMVC入门学习(十四)----SpringMVC实现RESTful风格

1、REST的概念

REST为“Representational State Transfer”的缩写,中文释义为“表现层状态转换”,REST不是一种标准,而是一种设计风格。是目前最流行的一种互联网软件架构风格。它倡导结构清晰、符合标准、易于理解、扩展方便的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 用来删除资源
HTTP方法名 使用场景 资源操作 是否幂等 是否安全
GET 从服务器取出资源(一项或多项) SELECT
POST 在服务器新建一个资源 INSERT
PUT 在服务器更新资源(客户端提供完整资源数据) UPDATE
DELETE 从服务器删除资源 DELETE
  • 幂等性:对同一REST接口的多次访问,得到的资源状态是相同的。
  • 安全性:对该REST接口访问,不会使服务器端资源的状态发生改变。

RESTful:就是符合REST原则的架构方式即可称为RESTful。

2、REST 风格的 URL 请求

一般在非RESTful风格设计的应用中基本上只使用POST、GET类型的HTTP动作方法,而在RESTful风格设计的应用中充分利用了HTTP协议的另外动作方法,统一了数据操作的接口,使得URL请求变得简洁化、透明化。

image

3、REST风格URL的好处

①、含蓄,安全:使用问号键值对的方式给服务器传递数据太明显,容易被人利用来对系统进行破坏。使用REST风格携带数据不再需要明显的暴露数据的名称。

②、风格统一:URL地址整体格式统一,从前到后始终都使用斜杠划分各个内容部分,用简单一致的格式表达语义。

③、无状态:在调用一个接口(访问、操作资源)的时候,可以不用考虑上下文,不用考虑当前状态,极大的降低了系统设计的复杂度。

④、严谨,规范:严格按照HTTP1.1协议中定义的请求方式本身的语义进行操作。

⑤、简洁,优雅:过去做增删改查操作需要设计4个不同的URL,现在一个就够了。

⑥、丰富的语义:通过URL地址就可以知道资源之间的关系,如下所示:

http://localhost:8080/shop
http://localhost:8080/shop/product
http://localhost:8080/shop/product/cellPhone
http://localhost:8080/shop/product/cellPhone/iPhone

4、SpringMVC对四种请求方式的支持

在@RequestMapping注解中,我们可以使用method熟悉来设置对四种请求的支持:

  • @RequestMapping(value = "/get",method = RequestMethod.GET)
  • @RequestMapping(value = "/post",method = RequestMethod.POST)
  • @RequestMapping(value = "/put",method = RequestMethod.PUT)
  • @RequestMapping(value = "/delete",method = RequestMethod.DELETE)

但是可以发现上面的注解中大体都是相似了,所以SpringMVC给我们提供了简化的版本:

  • @GetMapping(value = "/get"):对应GET请求
  • @PostMapping(value = "/post"):对应POST请求
  • @PutMapping(value = "/put"):对应PUT请求
  • @DeleteMapping(value = "/delete"):对应DELETE请求

注:在SpringMVC中对RESTful支持,主要通过注解来实现,所以下面再介绍三个相关注解:

  • @ResponseBody:响应内容转换为JSON格式
  • @RequestBody:请求内容转换为JSON格式
  • @RestContrller:等同@Controller+@ResponsrBody

浏览器对REST的支持:

由于浏览器表单只支持 GET 和 POST 请求,所以为了让浏览器实现 DELETE 和 PUT 请求,Spring 为我们提供了一个过滤器:org.springframework.web.filter.HiddenHttpMethodFilter,可以为我们将 GET 和 POST 请求通过过滤器转化成 PUT 或 DELETE 等其他形式。

下面是HiddenHttpMethodFilter的使用方法:

①在web.xml中进行配置,拦截所有资源,注意:它必须作用于解决乱码过滤器CharacterEncodingFilter的后面,否则处理乱码的过滤器就会失效。

<!-- 配置 org.springframework.web.filter.HiddenHttpMethodFilter 过滤器 -->
<filter>
    <filter-name>hiddenHttpMethodFilter</filter-name>
    <filter-class>org.springframework.web.filter.HiddenHttpMethodFilter</filter-class>
</filter>    
<filter-mapping>
    <filter-name>hiddenHttpMethodFilter</filter-name>
    <!-- 拦截所有请求 -->
    <url-pattern>/*</url-pattern>
</filter-mapping>

[1]、转PUT请求:

POST请求转为PUT请求非常简单,只需在表单隐藏域中通过_method请求参数附带请求方式名称即可。

<!-- 将POST请求转为PUT请求 -->
<!-- 表单需要按照HiddenHttpMethodFilter的要求来写 -->
<!-- 要求1:请求本身是必须是POST -->
<!-- 要求2:指定新请求方式的请求参数名称必须是_method -->
<form action="${pageContext.request.contextPath}/update/emp" method="post">
    <input type="hidden" name="_method" value="PUT" />
    .......
</form>

[2]、转DELETE请求:

通过点击超链接执行删除操作。这是一个难点,超链接中没有表单隐藏域,所以需要将超链接转换为表单进行提交,这就需要借助于JavaScript。

①、在页面上创建一个action属性为空的form表单

<!-- 将超链接的GET请求转换为DELETE请求 -->
<!-- 1、提供一个通用的表单,用来将GET请求先转换为POST,然后再发送_method请求参数 -->
<!-- action属性不能写死,将来点击哪一个超链接,目标地址就和那个超链接一致 -->
<form id="commonForm" action="" method="post">
<input type="hidden" name="_method" value="delete" />
</form>

②、给所有超链接绑定单击响应函数

<script type="text/javascript" src="${pageContext.request.contextPath}/script/jquery-1.7.2.js"></script>
<script type="text/javascript">
	$(function () {
		$(".removeEmp").click(function () {

			// 在单击响应函数中获取当前点击的超链接的URL地址
			var targetUrl = this.href;
			console.log(targetUrl);

			// 通过id获取到表单的jQuery对象,然后设置action属性值,再提交表单
			$("#commonForm").attr("action", targetUrl).submit();

			// 取消控件的默认行为
			return false;
		});
	});
</script>

③、超链接

<a class="removeEmp" href="${pageContext.request.contextPath}/remove/emp/1">模拟删除</a><br/>
<a class="removeEmp" href="${pageContext.request.contextPath}/remove/emp/2">模拟删除</a><br/>
<a class="removeEmp" href="${pageContext.request.contextPath}/remove/emp/3">模拟删除</a><br/>

5、@PathVariable注解

@PathVariable作用:通过URL地址携带的数据需要通过@PathVariable注解来获取。它的用法如下:

<a href="${pageContext.request.contextPath}/emp/2">一个参数情况</a><br/>
//请求路径为:/emp/2
@RequestMapping("/emp/{empId}")
public String testPathVariable(@PathVariable("empId") Integer empId) {
    System.out.println("empId="+empId);
    return "result";
}

对于请求路径中有多个数据,@PathVariable注解也是支持的。

<a href="${pageContext.request.contextPath}/send/message/tom/tell/jerry">多个参数情况</a><br/>
//请求路径为:/send/message/tom/tell/jerry
@RequestMapping("/send/message/{foo}/tell/{bar}")
public String sendMessage(@PathVariable("foo") String foo,
                          @PathVariable("bar") String bar) {
    System.out.println("foo = " + foo);
    System.out.println("bar = " + bar);
    return "target";
}
posted @ 2021-05-21 17:24  唐浩荣  阅读(484)  评论(0编辑  收藏  举报