圆咕噜咕噜 发表于 2024-7-4 21:23:02

Spring MVC 中使用 RESTFul 编程风格

1. Spring MVC 中使用RESTFul 编程风格

@
目录

[*]1. Spring MVC 中使用RESTFul 编程风格
[*]2. RESTFul 编程风格

[*]2.1 RESTFul 是什么
[*]2.2 RESTFul风格与传统方式对比

[*]3. Spring MVC 中使用RESTFul 编程风格(增删改查)的使用

[*]3.1 预备工作
[*]3.2 RESTFul 风格的 “查询” 所有(RESTFul 规范 需要发送 GET请求)
[*]3.3 RESTFul 风格的 根据 “id 查询”( RESTFul 规范 需要发送 GET请求)
[*]3.4 RESTFul 风格的 “增长数据” (RESTFul 规范 需要发送 POST 请求)
[*]3.5 RESTFul 风格的 “修改数据” (RESTFul 规范 需要发送 PUT 请求)
[*]3.6 RESTFul 风格的 “删除数据” 数据(RESTFul 规范 需要发送 DELETE 请求)

[*]4. 补充: HiddenHttpMethodFilter 过滤器源码阐明
[*]5. 总结:
[*]6. 末了:

2. RESTFul 编程风格

2.1 RESTFul 是什么

RESTFul 是 web 服务器接口 的一种计划风格。
RESTFul 定义了一组束缚条件和规范,可以让 web服务器接口 更加简洁,易于理解,易于扩展,安全可靠。
RESTFUl 对一个 web 服务器接口 都规定了哪些东西 ?

[*]对请求的 URL 格式有束缚和规范
[*]对 HTTP 的请求方式有束缚和规范
[*]对请求和响应的数据格式有束缚和规范
[*]对 HTTP 状态码有束缚和规范
[*]等......
REST 对请求方式的束缚是如许的:

[*]查询必须发送 GET 请求
[*]新增必须发送 POST 请求
[*]修改必须发送 PUT 请求
[*]删除必须发送 DELETE 请求
REST对 URL 的束缚时如许的:

[*]传统的 URL : get 请求,/springmvc/getUserById?id=1
[*]REST风格的 URL:get 请求,/springmvc/user/1
[*]传统的URL :get 请求,/springmvc/deleteUserById?id=1
[*]REST风格的URL:delete 请求,/springmvc/user/1
RESTFul 对 URL 的束缚和规范的焦点时:通过采用 :不同的请求方式   + URL 来确定 web 服务中的资源。
RESTFul 的英文全称时:Representational State Transfer(表述性状态转移),简称 REST。
表述性(Representational) 是:URL + 请求方式。
状态(State) 是 :服务器端的数据。
转移(Transfer) 是:变化。
表述性转移是指:通过 URL + 请求方式来控制服务器端数据的变化。
2.2 RESTFul风格与传统方式对比

统的 URL 与 RESTful URL 的区别是传统的 URL 是基于方法名举行资源访问和操纵,而 RESTful URL 是基于资源的结构和状态举行操纵的。下面是一张表格,展示两者之间的具体区别:
传统的 URLRESTful URLGET /getUserById?id=1GET /user/1GET /getAllUserGET /userPOST /addUserPOST /userPOST /modifyUserPUT /userGET /deleteUserById?id=1DELETE /user/1从上表中我们可以看出,传统的 URL是基于动作的,而 RESTful URL 是基于资源和状态的,因此 RESTful URL 更加清楚和易于理解,这也是 REST 架构风格被广泛使用的重要原因之一。
3. Spring MVC 中使用RESTFul 编程风格(增删改查)的使用

3.1 预备工作

导入相干依赖 jar 包。
https://img2024.cnblogs.com/blog/3084824/202407/3084824-20240704215808738-8844862.png
https://img2024.cnblogs.com/blog/3084824/202407/3084824-20240704215808772-679081597.png
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <groupId>com.rainbowsea</groupId>
    <artifactId>springmvc-007</artifactId>
    <version>1.0-SNAPSHOT</version>
    <packaging>war</packaging>

    <properties>
      <maven.compiler.source>17</maven.compiler.source>
      <maven.compiler.target>17</maven.compiler.target>
    </properties>





    <dependencies>
      
      <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-webmvc</artifactId>
            <version>6.1.4</version>
      </dependency>
      
      <dependency>
            <groupId>ch.qos.logback</groupId>
            <artifactId>logback-classic</artifactId>
            <version>1.5.3</version>
      </dependency>
      
      <dependency>
            <groupId>jakarta.servlet</groupId>
            <artifactId>jakarta.servlet-api</artifactId>
            <version>6.0.0</version>
            <scope>provided</scope>
      </dependency>
      
      <dependency>
            <groupId>org.thymeleaf</groupId>
            <artifactId>thymeleaf-spring6</artifactId>
            <version>3.1.2.RELEASE</version>
      </dependency>
    </dependencies>


</project>相干包 / 目录的创建,配置。
https://img2024.cnblogs.com/blog/3084824/202407/3084824-20240704215808657-1767196795.png
springmvc.xml 配置文件的配置;
https://img2024.cnblogs.com/blog/3084824/202407/3084824-20240704215808389-807867120.png
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:context="http://www.springframework.org/schema/context"
       xmlns:mvc="http://www.springframework.org/schema/mvc"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context https://www.springframework.org/schema/context/spring-context.xsd http://www.springframework.org/schema/cache http://www.springframework.org/schema/cache/spring-cache.xsd http://www.springframework.org/schema/mvc https://www.springframework.org/schema/mvc/spring-mvc.xsd">

   
    <context:component-scan base-package="com.rainbowsea.springmvc.controller"></context:component-scan>

   
    <bean id="thymeleafViewResolver" >
      
      <property name="characterEncoding" value="UTF-8"/>
      
      <property name="order" value="1"/>
      
      <property name="templateEngine">
            <bean >
               
                <property name="templateResolver">
                  <bean >
                        
                        <property name="prefix" value="/WEB-INF/templates/"/>
                        
                        <property name="suffix" value=".html"/>
                        
                        <property name="templateMode" value="HTML"/>
                        
                        <property name="characterEncoding" value="UTF-8"/>
                  </bean>
                </property>
            </bean>
      </property>
    </bean>

   
    <mvc:annotation-driven></mvc:annotation-driven>

   
    <mvc:view-controller path="/" view-name="index"></mvc:view-controller>

</beans>3.2 RESTFul 风格的 “查询” 所有(RESTFul 规范 需要发送 GET请求)

RESTFul 规范中规定,如果要查询数据,需要发送 GET 请求。
https://img2024.cnblogs.com/blog/3084824/202407/3084824-20240704215808419-1781635879.png
<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
    <meta charset="UTF-8">
    <title>首页</title>
</head>
<body>
<h1>测试 RESTFul 编程风格</h1>
<hr>

<a th:target="_blank" href="https://www.cnblogs.com/@{/user}">查看用户列表</a>

</body>
</html>控制器 Controller:
https://img2024.cnblogs.com/blog/3084824/202407/3084824-20240704215808276-256946805.png
import com.rainbowsea.springmvc.bean.User;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;

@Controller// 交给 Spring IOC 容器进行管理
public class UserController {

    @RequestMapping(value = "/user", method = RequestMethod.GET)
    public String getAll() {
      System.out.println("正在查询所有用户信息...");
      return "ok";
    }

}ok 的页面视图:
https://img2024.cnblogs.com/blog/3084824/202407/3084824-20240704215808339-799791149.png
<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
    <meta charset="UTF-8">
    <title>OK页面</title>
</head>
<body>

<h1>OK !</h1>

</body>
</html>启动服务器,测试:http://localhost:8080/springmvc
https://img2024.cnblogs.com/blog/3084824/202407/3084824-20240704215808392-1661312411.png
https://img2024.cnblogs.com/blog/3084824/202407/3084824-20240704215808863-987437795.png
https://img2024.cnblogs.com/blog/3084824/202407/3084824-20240704215808358-1093987916.png
3.3 RESTFul 风格的 根据 “id 查询”( RESTFul 规范 需要发送 GET请求)

RESTFul 规范中规定,如果要查询数据,需要发送GET请求。
首页index.html
https://img2024.cnblogs.com/blog/3084824/202407/3084824-20240704215808684-318027729.png
<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
    <meta charset="UTF-8">
    <title>首页</title>
</head>
<body>
<h1>测试 RESTFul 编程风格</h1>
<hr>

<a th:target="_blank" href="https://www.cnblogs.com/@{/user}">查看用户列表</a>

</body>
</html>查询id=1的这个用户信息
控制器 Controller:
https://img2024.cnblogs.com/blog/3084824/202407/3084824-20240704215808630-514907856.png
import com.rainbowsea.springmvc.bean.User;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;

@Controller// 交给 Spring IOC 容器进行管理
public class UserController {


    //@RequestMapping(value = "/user/{占位符}",method = RequestMethod.GET)
    @RequestMapping(value = "/user/{id}", method = RequestMethod.GET)
    public String getById(@PathVariable(value = "id") String id) {
      System.out.println("正在根据用户 id 查询用户信息...用户 id 是" + id);

      return "ok";
    }

}启动服务器测试:
https://img2024.cnblogs.com/blog/3084824/202407/3084824-20240704215808378-325281172.png
https://img2024.cnblogs.com/blog/3084824/202407/3084824-20240704215808739-1269287067.png
https://img2024.cnblogs.com/blog/3084824/202407/3084824-20240704215808745-875070962.png
3.4 RESTFul 风格的 “增长数据” (RESTFul 规范 需要发送 POST 请求)

RESTFul规范中规定,如果要举行保存操纵,需要发送POST请求。
这里我们添加一个 User Bean 类,用于作为对象举行存储。
https://img2024.cnblogs.com/blog/3084824/202407/3084824-20240704215808726-757748034.png
package com.rainbowsea.springmvc.bean;

public class User {
    private String username;
    private String password;
    private Integer age;

    public User() {
    }

    public User(String username, String password, Integer age) {
      this.username = username;
      this.password = password;
      this.age = age;
    }

    @Override
    public String toString() {
      return "User{" +
                "username='" + username + '\'' +
                ", password='" + password + '\'' +
                ", age=" + age +
                '}';
    }


    public String getUsername() {
      return username;
    }

    public void setUsername(String username) {
      this.username = username;
    }

    public String getPassword() {
      return password;
    }

    public void setPassword(String password) {
      this.password = password;
    }

    public Integer getAge() {
      return age;
    }

    public void setAge(Integer age) {
      this.age = age;
    }
}页面编写:
https://img2024.cnblogs.com/blog/3084824/202407/3084824-20240704215808472-2126432086.png
<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
    <meta charset="UTF-8">
    <title>首页</title>
</head>
<body>
<h1>测试 RESTFul 编程风格</h1>
<hr>

<a th:target="_blank" href="https://www.cnblogs.com/@{/user}">查看用户列表</a>

</body>
</html>查询id=1的这个用户信息
    用户名:
    密码:
    年岁:
    <hr>控制器 Controller:
https://img2024.cnblogs.com/blog/3084824/202407/3084824-20240704215808307-1697997292.png
启动服务器测试:
https://img2024.cnblogs.com/blog/3084824/202407/3084824-20240704215808367-254465449.png
https://img2024.cnblogs.com/blog/3084824/202407/3084824-20240704215808346-1857951126.png
3.5 RESTFul 风格的 “修改数据” (RESTFul 规范 需要发送 PUT 请求)

RESTFul规范中规定,如果要举行保存操纵,需要发送PUT请求。
如何发送PUT请求?
第一步:首先你必须是一个POST请求。
第二步:在发送POST请求的时候,提交如许的数据:_method=PUT ,使用隐藏域举行配置
https://img2024.cnblogs.com/blog/3084824/202407/3084824-20240704215808393-1515457661.png
第三步:在web.xml文件配置SpringMVC提供的过滤器:HiddenHttpMethodFilter
注意:

    <input type="hidden" name="_method" value="put">
隐藏域的 name 必须只能是 “_method”, value是 put(大小写忽略)第一步:首先你必须是一个POST请求。
第二步:在发送POST请求的时候,提交如许的数据:_method=PUT
https://img2024.cnblogs.com/blog/3084824/202407/3084824-20240704215808712-1063720063.png
<h2>修改</h2>

<form th:action="@{/user}" method="post">
   
    <input type="hidden" name="_method" value="put">

    用户名: <input type="text" name="username">

    密码:<input type="password" name="password">

    年龄: <input type="text" name="age">

    <input type="submit" value="修改">

</form>https://img2024.cnblogs.com/blog/3084824/202407/3084824-20240704215808862-1678754230.png
第三步:在web.xml文件配置SpringMVC提供的过滤器:HiddenHttpMethodFilter
注意:该过滤器一定要在字符编码过滤器背面配置,不然,先设置的话,可能会出现获取到的请求数据是乱码
https://img2024.cnblogs.com/blog/3084824/202407/3084824-20240704215808810-984875289.png
   


    <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>页面编写:
https://img2024.cnblogs.com/blog/3084824/202407/3084824-20240704215808802-462639846.png
<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
    <meta charset="UTF-8">
    <title>首页</title>
</head>
<body>
<h1>测试 RESTFul 编程风格</h1>
<hr>

<a th:target="_blank" href="https://www.cnblogs.com/@{/user}">查看用户列表</a>

</body>
</html>查询id=1的这个用户信息
    用户名:
    密码:
    年岁:
    <hr><h2>修改</h2>

<form th:action="@{/user}" method="post">
   
    <input type="hidden" name="_method" value="put">

    用户名: <input type="text" name="username">

    密码:<input type="password" name="password">

    年龄: <input type="text" name="age">

    <input type="submit" value="修改">

</form>控制器 Controller:
https://img2024.cnblogs.com/blog/3084824/202407/3084824-20240704215808255-1092385487.png
启动服务器测试:
https://img2024.cnblogs.com/blog/3084824/202407/3084824-20240704215808664-1495686266.png
https://img2024.cnblogs.com/blog/3084824/202407/3084824-20240704215808283-1960351268.png
3.6 RESTFul 风格的 “删除数据” 数据(RESTFul 规范 需要发送 DELETE 请求)

RESTFul规范中规定,如果要举行 删除 操纵,需要发送DELETE 请求。
如何发送 DELETE 请求?,和 发送PUT 请求的三步是一样的,只需要将 value 的值改为 delete 即可
第一步:首先你必须是一个POST请求。
第二步:在发送POST请求的时候,提交如许的数据:_method=PUT ,使用隐藏域举行配置
https://img2024.cnblogs.com/blog/3084824/202407/3084824-20240704215808755-1984457275.png
第三步:在web.xml文件配置SpringMVC提供的过滤器:HiddenHttpMethodFilter
注意:

    <input type="hidden" name="_method" value="delete">
隐藏域的 name 必须只能是 “_method”, value是 delete (大小写忽略)页面编写:
https://img2024.cnblogs.com/blog/3084824/202407/3084824-20240704215808409-1422018089.png
<hr>
<h2>删除用户</h2>




<a th:target="_blank" href="https://www.cnblogs.com/@{user/120}" onclick="del(event)">删除用户id = 120 的用户信息</a>
<form id="delForm" method="post">
    <input type="hidden" name="_method" value="delete">
</form><!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
    <meta charset="UTF-8">
    <title>首页</title>
</head>
<body>
<h1>测试 RESTFul 编程风格</h1>
<hr>

<a th:target="_blank" href="https://www.cnblogs.com/@{/user}">查看用户列表</a>

</body>
</html>查询id=1的这个用户信息
    用户名:
    密码:
    年岁:
    <hr><h2>修改</h2>

<form th:action="@{/user}" method="post">
   
    <input type="hidden" name="_method" value="put">

    用户名: <input type="text" name="username">

    密码:<input type="password" name="password">

    年龄: <input type="text" name="age">

    <input type="submit" value="修改">

</form><hr>
<h2>删除用户</h2>




<a th:target="_blank" href="https://www.cnblogs.com/@{user/120}" onclick="del(event)">删除用户id = 120 的用户信息</a>
<form id="delForm" method="post">
    <input type="hidden" name="_method" value="delete">
</form>控制器 Controller:
https://img2024.cnblogs.com/blog/3084824/202407/3084824-20240704215808721-54033890.png
package com.rainbowsea.springmvc.controller;


import com.rainbowsea.springmvc.bean.User;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;

@Controller// 交给 Spring IOC 容器进行管理
public class UserController {


    //@RequestMapping(value = "/user/{占位符}",method = RequestMethod.GET)
    @RequestMapping(value = "/user/{id}", method = RequestMethod.GET)
    public String getById(@PathVariable(value = "id") String id) {
      System.out.println("正在根据用户 id 查询用户信息...用户 id 是" + id);

      return "ok";
    }



    @RequestMapping(value = "/user", method = RequestMethod.GET)
    public String getAll() {
      System.out.println("正在查询所有用户信息...");
      return "ok";
    }




    @RequestMapping(value = "/user", method = RequestMethod.POST)
    public String save(User user) {
      System.out.println("正在保存用户信息");
      System.out.println(user);
      return "ok";
    }



    @RequestMapping(value = "/user", method = RequestMethod.PUT)
    public String modify(User user) {
      System.out.println("正在修改用户信息" + user);

      return "ok";
    }



    @RequestMapping(value = "/user/{id}", method = RequestMethod.DELETE)
    public String del(@PathVariable(value = "id") String id) {
      System.out.println("正删除用户 : " + id);

      return "ok";
    }

}启动服务器测试:
https://img2024.cnblogs.com/blog/3084824/202407/3084824-20240704215808369-941337698.png
https://img2024.cnblogs.com/blog/3084824/202407/3084824-20240704215808727-282542983.png
4. 补充: HiddenHttpMethodFilter 过滤器源码阐明

HiddenHttpMethodFilter是Spring MVC框架提供的,专门用于RESTFul编程风格。
实现原理可以通过源码查看:
https://img2024.cnblogs.com/blog/3084824/202407/3084824-20240704215808478-1877419354.png
https://img2024.cnblogs.com/blog/3084824/202407/3084824-20240704215808805-476621641.png
https://img2024.cnblogs.com/blog/3084824/202407/3084824-20240704215808678-1580831234.png
通过源码可以看到,if语句中,首先判断是否为POST请求,如果是POST请求,调用request.getParameter(this.methodParam)。可以看到this.methodParam是_method,如许就要求我们在提交请求方式的时候必须采用这个格式:_method=put。获取到请求方式之后,调用了toUpperCase转换成大写了。因此前端页面中小写的put或者大写的PUT都是可以的。if语句中嵌套的if语句说的是,只有请求方式是 PUT,DELETE,PATCH的时候会创建HttpMethodRequestWrapper对象。而HttpMethodRequestWrapper对象的构造方法是如许的:
https://img2024.cnblogs.com/blog/3084824/202407/3084824-20240704215808357-178104928.png
如许method就从POST酿成了:PUT/DELETE/PATCH。
重点注意事项:CharacterEncodingFilter和HiddenHttpMethodFilter的顺序
细心的同学应该注意到了,在HiddenHttpMethodFilter源码中有如许一行代码:
https://img2024.cnblogs.com/blog/3084824/202407/3084824-20240704215808343-243049225.png
)
大家是否还记得,字符编码过滤器执行之前不能调用 request.getParameter方法,如果提前调用了,乱码问题就无法办理了。因为request.setCharacterEncoding()方法的执行必须在所有request.getParameter()方法之前执行。因此这两个过滤器就有先后顺序的要求,在web.xml文件中,应该先配置CharacterEncodingFilter,然后再配置HiddenHttpMethodFilter。
5. 总结:


[*]RESTFul风格与传统方式对比区别
[*]RESTFul 风格的 “查询” 所有(RESTFul 规范 需要发送 GET请求)
[*]RESTFul 风格的 根据 “id 查询”( RESTFul 规范 需要发送 GET请求)
[*]RESTFul 风格的 “增长数据” (RESTFul 规范 需要发送 POST 请求)
[*]RESTFul 风格的 “修改数据” (RESTFul 规范 需要发送 PUT 请求)
如何发送PUT请求?
第一步:首先你必须是一个POST请求。
第二步:在发送POST请求的时候,提交如许的数据:_method=PUT ,使用隐藏域举行配置
https://img2024.cnblogs.com/blog/3084824/202407/3084824-20240704215808860-1291180559.png
第三步:在web.xml文件配置SpringMVC提供的过滤器:HiddenHttpMethodFilter**
注意:

    <input type="hidden" name="_method" value="put">
隐藏域的 name 必须只能是 “_method”, value是 put(大小写忽略)
[*]RESTFul 风格的 “删除数据” 数据(RESTFul 规范 需要发送 DELETE 请求);如何发送 DELETE 请求?,和 发送PUT 请求的三步是一样的,只需要将 value 的值改为 delete 即可
[*]HiddenHttpMethodFilter该过滤器一定要在字符编码过滤器背面配置,不然,先设置的话,可能会出现获取到的请求数据是乱码。
6. 末了:

“在这个末了的篇章中,我要表达我对每一位读者的感激之情。你们的关注和回复是我创作的动力源泉,我从你们身上汲取了无尽的灵感与勇气。我会将你们的鼓励留在心底,继续在其他的领域奋斗。感谢你们,我们总会在某个时刻再次相遇。”
https://img2024.cnblogs.com/blog/3084824/202407/3084824-20240704215808737-573509215.gif

免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。
页: [1]
查看完整版本: Spring MVC 中使用 RESTFul 编程风格