SpringMVC系列(三):REST風格


一、什么叫REST

REST:即 Representational State Transfer。(資源)表現層狀態轉化。是目前最流行的一種互聯網軟件架構。它結構清晰、符合標准、易於理解、擴展方便,所以正得到越來越多網站的采用

• 資源(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 用來刪除資源。

二、看完上面對REST的解釋是不是一臉懵比呢,沒關系我們通過代碼實例來解讀

 實際上REST就是一種新型的CRUD操作方式,那么SpringMVC是怎么實現的呢

1. 需要在web.xml配置 HiddenHttpMethodFilter

 1 <?xml version="1.0" encoding="UTF-8"?>
 2 <web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
 3     xmlns="http://java.sun.com/xml/ns/javaee"
 4     xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
 5     id="WebApp_ID" version="2.5">
 6 
 7    <!-- 
 8     配置 org.springframework.web.filter.HiddenHttpMethodFilter: 可以把 POST 請求轉為 DELETE 或 put 請求 
 9     -->
10     <filter>
11         <filter-name>HiddenHttpMethodFilter</filter-name>
12         <filter-class>org.springframework.web.filter.HiddenHttpMethodFilter</filter-class>
13     </filter>
14     
15     <filter-mapping>
16         <filter-name>HiddenHttpMethodFilter</filter-name>
17         <url-pattern>/*</url-pattern>
18     </filter-mapping>
19     
20     <!-- 配置 DispatcherServlet -->
21     <servlet>
22         <servlet-name>dispatcherServlet</servlet-name>
23         <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
24         <!-- 配置 DispatcherServlet 的一個初始化參數: 配置 SpringMVC 配置文件的位置和名稱 -->
25         <!-- 
26             實際上也可以不通過 contextConfigLocation 來配置 SpringMVC 的配置文件, 而使用默認的.
27             默認的配置文件為: /WEB-INF/<servlet-name>-servlet.xml
28         -->
29         <init-param>
30             <param-name>contextConfigLocation</param-name>
31             <param-value>classpath:springmvc.xml</param-value>
32         </init-param>
33         <!-- 加載時創建 -->
34         <load-on-startup>1</load-on-startup>
35     </servlet>
36 
37     <!-- dispatcherServlet可以應答所有請求 -->
38     <servlet-mapping>
39         <servlet-name>dispatcherServlet</servlet-name>
40         <url-pattern>/</url-pattern>
41     </servlet-mapping>
42 
43 </web-app>

HiddenHttpMethodFilter源碼:

 1 @Override
 2     protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain)
 3             throws ServletException, IOException {
 4 
 5         HttpServletRequest requestToUse = request;
 6 
 7         if ("POST".equals(request.getMethod()) && request.getAttribute(WebUtils.ERROR_EXCEPTION_ATTRIBUTE) == null) {
 8             String paramValue = request.getParameter(this.methodParam);
 9             if (StringUtils.hasLength(paramValue)) {
10                 requestToUse = new HttpMethodRequestWrapper(request, paramValue);
11             }
12         }
13 
14         filterChain.doFilter(requestToUse, response);
15     }

通過源碼可以知道SpringMVC可以把post請求轉換為delete和put,我們只需要在發送 POST 請求時攜帶一個 name="_method" 的隱藏域, 值為 DELETE 或 PUT即可

2.在index.jsp編寫REST風格的CRUD請求

 1 <!--Rest風格 begin  --> 
 2 <br/>
 3 <a href="restTest/testRest/1">Test Rest Get</a>
 4 
 5 <br/>
 6 <form action="restTest/testRest" method="post">
 7         <input type="submit" value="TestRest POST"/>
 8 </form>
 9 
10 <br/>
11 <form action="restTest/testRest/1" method="post">
12     <input type="hidden" name="_method" value="DELETE"/>
13     <input type="submit" value="TestRest DELETE"/>
14 </form>
15 
16 <br/>
17 <form action="restTest/testRest/1" method="post">
18         <input type="hidden" name="_method" value="PUT"/>
19         <input type="submit" value="TestRest PUT"/>
20 </form>
21 <!--Rest風格 end  --> 

3.編寫handler

 1 package com.study.springmvc.handlers;
 2 
 3 import org.springframework.stereotype.Controller;
 4 import org.springframework.web.bind.annotation.PathVariable;
 5 import org.springframework.web.bind.annotation.RequestMapping;
 6 import org.springframework.web.bind.annotation.RequestMethod;
 7 
 8 @RequestMapping("/restTest")
 9 @Controller
10 public class RestTest {
11 
12     public static final String SUCCESS="success";
13     
14     /**
15      * Rest 風格的 URL. 
16      * 以 CRUD 為例: 
17      * 新增: /order POST 
18      * 修改: /order/1 PUT update?id=1 
19      * 獲取: /order/1 GET get?id=1 
20      * 刪除: /order/1 DELETE delete?id=1
21      * 
22      * 如何發送 PUT 請求和 DELETE 請求呢 ? 
23      * 1. 需要在web.xml配置 HiddenHttpMethodFilter 
24      * 2. 需要發送 POST 請求
25      * 3. 需要在發送 POST 請求時攜帶一個 name="_method" 的隱藏域, 值為 DELETE 或 PUT
26      * 
27      * 在 SpringMVC 的目標方法中如何得到 id 呢? 使用 @PathVariable 注解
28      * 
29      */
30     
31     /**
32      * Rest風格:get請求
33      * @param id
34      * @return
35      */
36     @RequestMapping(value = "/testRest/{id}", method = RequestMethod.GET)
37     public String testRest(@PathVariable Integer id) {
38         System.out.println("testRest GET: " + id);
39         return SUCCESS;
40     }
41     
42     /**
43      * Rest風格:post請求
44      * @param id
45      * @return
46      */
47     @RequestMapping(value = "/testRest", method = RequestMethod.POST)
48     public String testRest() {
49         System.out.println("testRest POST");
50         return SUCCESS;
51     }
52     
53     /**
54      * Rest風格:delete請求
55      * @param id
56      * @return
57      */
58     @RequestMapping(value = "/testRest/{id}", method = RequestMethod.DELETE)
59     public String testRestDelete(@PathVariable Integer id) {
60         System.out.println("testRest Delete: " + id);
61         return SUCCESS;
62     }
63     
64     /**
65      * Rest風格:put請求(更新)
66      * @param id
67      * @return
68      */
69     @RequestMapping(value = "/testRest/{id}", method = RequestMethod.PUT)
70     public String testRestPut(@PathVariable Integer id) {
71         System.out.println("testRest Put: " + id);
72         return SUCCESS;
73     }
74 
75 }

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM