zoukankan      html  css  js  c++  java
  • 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";
    }
    
    作者: 唐浩荣
    本文版权归作者和博客园共有,欢迎转载,但是转载需在博客的合适位置给出原文链接,否则保留追究法律责任的权利。
  • 相关阅读:
    bzoj 4012: [HNOI2015]开店
    POJ 1054 The Troublesome Frog
    POJ 3171 Cleaning Shifts
    POJ 3411 Paid Roads
    POJ 3045 Cow Acrobats
    POJ 1742 Coins
    POJ 3181 Dollar Dayz
    POJ 3040 Allowance
    POJ 3666 Making the Grade
    洛谷 P3657 [USACO17FEB]Why Did the Cow Cross the Road II P
  • 原文地址:https://www.cnblogs.com/tanghaorong/p/14765947.html
Copyright © 2011-2022 走看看