• 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 }
  • 相关阅读:
    宫立秋20201015-3 每周例行报告
    宫立秋 20201008-1 每周例行报告
    分析“中国铁路12306”查询某个火车经过的车站和预计到达时间的request请求和respond响应。
    来自童晶老师的游戏开发课程作业
    飞机大战
    总结
    20201207-总结
    实时时钟
    作业要求 20201126-1 每周例行报告
    要求 20201120-1 每周例行报告
  • 原文地址:https://www.cnblogs.com/leeSmall/p/7806606.html
Copyright © 2020-2023  润新知