转载和引用,请注明原文出处! Fork me on GitHub
结局很美妙的事,开头并非如此!

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 }

 

posted @ 2017-11-08 22:22  小不点啊  阅读(2473)  评论(0编辑  收藏  举报