RESTful

RESTful

简介

REST(Representational State Transfer):表现层资源状态转移
①资源
资源是一种看待服务器的方式,即,将服务器看作是由很多离散的资源组成。每个资源是服务器上可命名的抽象概念。因为资源是一种抽象概念,所以它不仅仅能代表服务器文件系统中的一个文件、数据库中的一张表等等具体的东西,与面向对象设计类似,资源是以名词为核心来阻止的。一个资源可以由一个或多个URL来标识。URL既是资源的名称,也是资源在web上的地址。
②资源的描述
资源的描述是一段对于资源在某个特定的时刻的转台的描述,可以在客户端-服务器之间转移(交换),资源的表述含可以核对格式。如HTML/XML/JSON/纯文本等。资源的表述格式可以通过协商机制来确定,请求-响应方式的表述通常使用不同的格式。
③状态转移
状态转移说的是:在客户端-服务器之间转移(transfer)代表资源状态的表述。通过转移和操作资源的表述来间接实现操作资源的目的。

RESTful实现

具体说,就是http协议里面,四个标识操作方式的动词:GET、POST、PUT、DELETE
它们分别对应四种基本操作:GET用来获取资源、POST用来新建资源、PUT用来更新资源、DELETE用来删除资源。
REST风格提倡URL地址使用同一风格设计,从前到后各个单词是使用斜杠分开,不适用问号键值对方式形式携带请求参数。而不是将发送给服务器的数据作为URL地址的一部分,以保证整体风格的一致性。

操作 传统方式 REST风格
查询操作 getUserById?id=1 user/1---->get请求方式
新增操作 saveUser user----->post请求方式
删除操作 deleteUser?id=1 user/1---->delete请求
更新操作 updateUser user—>put请求

GET、POST的REST风格

示例

①创建模块完善maven目录结构
②导入依赖
<dependency>
    <groupId>javax.servletgroupId>
    <artifactId>javax.servlet-apiartifactId>
    <version>4.0.1version>
dependency>
<dependency>
    <groupId>org.springframeworkgroupId>
    <artifactId>spring-webmvcartifactId>
    <version>5.3.1version>
dependency>
<dependency>
    <groupId>org.thymeleafgroupId>
    <artifactId>thymeleaf-spring5artifactId>
    <version>3.0.12.RELEASEversion>
dependency>
③配置web.xml配置文件
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd"
         version="4.0">

  <filter>
    <filter-name>CharacterEncodingFilterfilter-name>
    <filter-class>org.springframework.web.filter.CharacterEncodingFilterfilter-class>
    <init-param>
      
      <param-name>encodingparam-name>
      <param-value>UTF-8param-value>
    init-param>
    <init-param>
      
      <param-name>forceResponseEncodingparam-name>
      <param-value>trueparam-value>
    init-param>
  filter>
  <filter-mapping>
    <filter-name>CharacterEncodingFilterfilter-name>
    <url-pattern>/*url-pattern>
  filter-mapping>
  
  <servlet>
    <servlet-name>springMVCRESTservlet-name>
    <servlet-class>org.springframework.web.servlet.DispatcherServletservlet-class>
    <init-param>
      <param-name>contextConfigLocationparam-name>
      <param-value>classpath:SpringMVCRESTFul.xmlparam-value>
    init-param>
    <load-on-startup>1load-on-startup>
  servlet>
  <servlet-mapping>
    <servlet-name>springMVCRESTservlet-name>
    <url-pattern>/url-pattern>
  servlet-mapping>
web-app>
④创建并配置SpringMVCRESTFul.xml

<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/mvc
       http://www.springframework.org/schema/mvc/spring-mvc.xsd
       http://www.springframework.org/schema/beans
       http://www.springframework.org/schema/beans/spring-beans.xsd
       http://www.springframework.org/schema/context
       http://www.springframework.org/schema/context/spring-context.xsd">

    <context:component-scan base-package="com.louis.controller">context:component-scan>
    
    <bean id="viewResolver" class="org.thymeleaf.spring5.view.ThymeleafViewResolver">
        <property name="order" value="1"/>
        <property name="characterEncoding" value="UTF-8"/>
        <property name="templateEngine">
            <bean class="org.thymeleaf.spring5.SpringTemplateEngine">
                <property name="templateResolver">
                    <bean class="org.thymeleaf.spring5.templateresolver.SpringResourceTemplateResolver">
                        <property name="prefix" value="/WEB-INF/templates/"/>
                        <property name="suffix" value=".html"/>
                        <property name="templateMode" value="HTML5"/>
                        <property name="characterEncoding" value="UTF-8"/>
                    bean>
                property>
            bean>
        property>
    bean>
    
    <mvc:view-controller path="/" view-name="test_REST">mvc:view-controller>
    <mvc:annotation-driven>mvc:annotation-driven>
beans>
⑤编写页面跳转成功页面success.html
DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8" xmlns:th="http://www.thymeleaf.org">
    <title>Titletitle>
head>
<body>
恭喜!成功了!
body>
html>
⑥编写test_REST.html文件
DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8" xmlns:th="http://www.thymeleaf.org">
    <title>Titletitle>
head>
<body>
<a th:href="@{/user}">查询所有用户信息a><br/>
<a th:href="@{/user/1}">根据id查询用户信息a><br/>
<form th:action="@{/user}" method="post">
    用户名:<input type="text" name="username"><br/>
    密码:<input type="password" name="password"><br/>
    <input type="submit" value="添加"><br/>
form>
body>
html>
⑦设置控制器UserController
@Controller
public class UserController {
    /**
     * 使用RESTFul模拟用户资源增删改查
     * /user GET   查询所有的用户信息
     * /user/1 GET   根据用户id查询用户信息
     * /user POST   添加用户信息
     * /user/1 DELETE   删除用户信息
     * /user PUT   修改用户信息
     */

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

    @RequestMapping(value = "/user/{id}", method = RequestMethod.GET)
    public String getUserById(){
        System.out.println("根据用户ID查询用户信息");
        return "success";
    }

    @RequestMapping(value = "/user", method = RequestMethod.POST)
    public String insertUser(String username, String password){
        System.out.println("username = " + username +  "  password = " + password);
        return "success";
    }
}
⑧测试

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

PUT、DELETE的REST风格

需要注意的是,不能直接使用PUT和DELETE操作,在SpringMVC中提供了一个过滤器(HiddenHttpMethodFilter),它是一个隐藏的HTTP请求方式,想要获取PUT和DELETE请求,必须满足两个条件,条件一是请求方式必须为POST,条件二是必须传输一个参数_method,但是它不需要用户传入,是一个隐藏的参数。

web.xml配置HiddenHttpMethodFilter


  <filter>
    <filter-name>HiddenHttpMethodFilterfilter-name>
    <filter-class>org.springframework.web.filter.HiddenHttpMethodFilterfilter-class>
  filter>
  <filter-mapping>
    <filter-name>HiddenHttpMethodFilterfilter-name>
    <url-pattern>/*url-pattern>
  filter-mapping>

注意:在配置文件中有多个过滤器的时候,由的前后顺序决定,所以为了正确性,需要将设置编码的过滤武器放在首位。

PUT示例

test_REST.html
<form th:action="@{/user}" method="post">
    
    <input type="hidden" name="_method" value="put">
    
    用户名:<input type="text" name="username"><br/>
    密码:<input type="password" name="password"><br/>
    <input type="submit" value="修改"><br/>
form>
UserController
@RequestMapping(value = "/user", method = RequestMethod.PUT)
public String updateUser(String username, String password){
    System.out.println("修改用户信息 = " + username + "," + password);
    return "success";
}

在这里插入图片描述

在这里插入图片描述

DELETE请求

和(修改)PUT请求不同的是,删除(DELETE)通常是超链接。所以在实现删除操作的时候的思路是在超链接上绑定点击事件,在点击事件中需要先阻止超链接的跳转,获得当前的某一个表单,将表单的提交方式设置为post,在其中添加一个隐藏域,设置name=“_method”。

RESTful完整案例

场景:在不连接数据库的情况下使用静态数据集合实现员工信息的增删改查。

1、准备工作

环境搭建

①创建模块并完善项目结构

RESTful_第1张图片

②导入依赖
<dependency>
    <groupId>javax.servletgroupId>
    <artifactId>javax.servlet-apiartifactId>
    <version>4.0.1version>
dependency>
<dependency>
    <groupId>org.springframeworkgroupId>
    <artifactId>spring-webmvcartifactId>
    <version>5.3.1version>
dependency>
<dependency>
    <groupId>org.thymeleafgroupId>
    <artifactId>thymeleaf-spring5artifactId>
    <version>3.0.12.RELEASEversion>
dependency>
③配置web.xml
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd"
         version="4.0">
  
  <filter>
    <filter-name>CharacterEncodingFilterfilter-name>
    <filter-class>org.springframework.web.filter.CharacterEncodingFilterfilter-class>
    <init-param>
      <param-name>encodingparam-name>
      <param-value>UTF-8param-value>
    init-param>
    <init-param>
      <param-name>forceResponseEncodingparam-name>
      <param-value>trueparam-value>
    init-param>
  filter>
  <filter-mapping>
    <filter-name>CharacterEncodingFilterfilter-name>
    <url-pattern>/*url-pattern>
  filter-mapping>
  
  <filter>
    <filter-name>HiddenHttpMethodFilterfilter-name>
    <filter-class>org.springframework.web.filter.HiddenHttpMethodFilterfilter-class>
  filter>
  <filter-mapping>
    <filter-name>HiddenHttpMethodFilterfilter-name>
    <url-pattern>/*url-pattern>
  filter-mapping>
  
  <servlet>
    <servlet-name>DispatcherServletservlet-name>
    <servlet-class>org.springframework.web.servlet.DispatcherServletservlet-class>
    <init-param>
      <param-name>contextConfigLocationparam-name>
      <param-value>classpath:springMVC.xmlparam-value>
    init-param>
    
    <load-on-startup>1load-on-startup>
  servlet>
  <servlet-mapping>
    <servlet-name>DispatcherServletservlet-name>
    <url-pattern>/url-pattern>
  servlet-mapping>
web-app>
④创建并配置springMVC.xml

<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:context="http://www.springframework.org/schema/context"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xsi:schemaLocation="
       http://www.springframework.org/schema/context
       http://www.springframework.org/schema/context/spring-context.xsd
       http://www.springframework.org/schema/beans
       http://www.springframework.org/schema/beans/spring-beans.xsd">

    
    <context:component-scan base-package="com.louis">context:component-scan>
    
    <bean id="viewResolver" class="org.thymeleaf.spring5.view.ThymeleafViewResolver">
        <property name="order" value="1"/>
        <property name="characterEncoding" value="UTF-8"/>
        <property name="templateEngine">
            <bean class="org.thymeleaf.spring5.SpringTemplateEngine">
                <property name="templateResolver">
                    <bean class="org.thymeleaf.spring5.templateresolver.SpringResourceTemplateResolver">
                        <property name="prefix" value="/WEB-INF/templates/"/>
                        <property name="suffix" value=".html"/>
                        <property name="templateMode" value="HTML5"/>
                        <property name="characterEncoding" value="UTF-8"/>
                    bean>
                property>
            bean>
        property>
    bean>
beans>
⑤创建实体类User
package com.louis.bean;

/**
 * @author XRY
 * @date 2023年07月01日16:33
 */
public class User {
    private Integer id;
    private String username;
    private String email;
    private Integer gender;

    public User() {
    }

    public User(Integer id, String username, String email, Integer gender) {
        this.id = id;
        this.username = username;
        this.email = email;
        this.gender = gender;
    }

    public Integer getId() {
        return id;
    }

    public void setId(Integer id) {
        this.id = id;
    }

    public String getUsername() {
        return username;
    }

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

    public String getEmail() {
        return email;
    }

    public void setEmail(String email) {
        this.email = email;
    }

    public Integer getGender() {
        return gender;
    }

    public void setGender(Integer gender) {
        this.gender = gender;
    }

    @Override
    public String toString() {
        return "User{" +
                "id=" + id +
                ", username='" + username + '\'' +
                ", email='" + email + '\'' +
                ", gender='" + gender + '\'' +
                '}';
    }
}
⑥创建UserDao
public class UserDao {
    private static Map<Integer, User> users = null;

        static{
            users = new HashMap<Integer, User>();

            users.put(1001, new User(1001, "E-AA", "[email protected]", 1));
            users.put(1002, new User(1002, "E-BB", "[email protected]", 1));
            users.put(1003, new User(1003, "E-CC", "[email protected]", 0));
            users.put(1004, new User(1004, "E-DD", "[email protected]", 0));
            users.put(1005, new User(1005, "E-EE", "[email protected]", 1));
        }

        private static Integer initId = 1006;
        //新增和修改的方法
        public void save(User user){
            if(user.getId() == null){
                user.setId(initId++);
            }
            users.put(user.getId(), user);
        }
        //查询全部
        public Collection<User> getAll(){
            return users.values();
        }
        //通过Id查询
        public User get(Integer id){
            return users.get(id);
        }
        //通过Id删除
        public void delete(Integer id){
            users.remove(id);
        }
}
⑦创建UserController
package com.louis.controller;

import com.louis.dao.UserDao;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;

/**
 * @author XRY
 * @date 2023年07月03日19:30
 */
@Controller
public class UserController {
    @Autowired
    private UserDao userDao;
}

RESTful_第2张图片

2、功能模块

功能清单

功能 URL地址 请求方式
访问首页 / GET
查询全部数据 /user GET
删除 /user/2 DELETE
跳转到添加页面 /toAdd GET
执行保存操作 /user POST
跳转到更新页面 /user/2 GET
执行更新 /user PUT
①访问首页

在templates下创建首页index.html

DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8" xmlns:th="http://www.thymeleaf.org">
    <title>首页title>
head>
<body>
<h3>首页h3>
<a th:href="@{/user}">查看员工信息a>
body>
html>

在配置文件springMVC.xml中添加标签

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

在这里插入图片描述

②查询数据
@Controller
public class UserController {
    @Autowired
    private UserDao userDao;

    @RequestMapping(value = "/user", method = RequestMethod.GET)
    public String getAllUser(Model model){
        /*只需要将数据放在一个较小的域中即可*/
        Collection<User> userList = userDao.getAll();
        model.addAttribute("userList", userList);
        return "employee_list";
    }
}

创建user_list.html用来显示数据

DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8" xmlns:th="http://www.thymeleaf.org">
    <title>Employee Infotitle>
head>
<body>
<table border="1" cellspacing="0" cellpadding="0" style="text-align: center">
    <tr>
        
        <th colspan="5">Employee Infoth>
    tr>
    <tr>
        <th>idth>
        <th>usernameth>
        <th>emailth>
        <th>genderth>
        <th>optionsth>
    tr>

    <tr th:each="user : ${userList}">
        <td th:text="${user.id}">td>
        <td th:text="${user.username}">td>
        <td th:text="${user.email}">td>
        <td th:text="${user.gender}">td>
        <td>
            <a href="">deletea>
            <a href="">updatea>
        td>
    tr>
table>
body>
html>

RESTful_第3张图片

③删除数据

不能通过超链接发送请求,需要通过超链接控制表单。
获取需要删除的id,使用vue将超链接和表单连接,需要引入vue。

在这里插入图片描述

user_list.html

DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8" xmlns:th="http://www.thymeleaf.org">
    <title>Employee Infotitle>
head>
<body>
<table id="dataTable" border="1" cellspacing="0" cellpadding="0" style="text-align: center">
    <tr>
        
        <th colspan="5">Employee Infoth>
    tr>
    <tr>
        <th>idth>
        <th>usernameth>
        <th>emailth>
        <th>genderth>
        <th>optionsth>
    tr>

    <tr th:each="user : ${userList}">
        <td th:text="${user.id}">td>
        <td th:text="${user.username}">td>
        <td th:text="${user.email}">td>
        <td th:text="${user.gender}">td>
        <td>
            
            
            <a @click="deleteUser" th:href="@{'/user/'+${user.id}}">deletea>
            <a href="">updatea>
        td>
    tr>
table>

<form id="deleteForm" method="post">
    <input type="hidden" value="delete" name="_method">
form>
<script type="text/javascript" th:src="@{/static/js/vue.js}">script>
<script type="text/javascript">
    var vue = new Vue({
        /*需要绑定容器,包裹需要操作的标签*/
        el:"#dataTable",
        /*需要在超链接上绑定点击事件*/
        methods:{
            deleteUser(event){
                /*获取当前form表单,添加deleteForm*/
                let deleteForm = document.getElementById("deleteForm");
                /*设置form表单的提交路径与超链接地址一致*/
                deleteForm.action = event.target.href;
                /*提交表单*/
                deleteForm.submit();
                /*取消标签的默认行为,阻止超链接直接跳转*/
                event.preventDefault();
            }
        }
    })
script>
body>
html>

创建删除的控制器

@RequestMapping(value = "/user/{id}", method = RequestMethod.DELETE)
public String deleteUser(@PathVariable("id") Integer id){
    userDao.delete(id);
    /*删除之后与原来的表单就没有数据连接了*/
    return "redirect:/user";
}

需要注意资源未引入的情况,需要重新进行打包。

RESTful_第4张图片

重新打包

RESTful_第5张图片

以上是解决服务器中没有vue资源文件,同时vue需要被默认的servlet处理,在springMVC中添加开放对静资源访问标签


<mvc:default-servlet-handler/>

测试

在这里插入图片描述

④添加功能

在表头部分的action表格中加入一个添加的超链接。

user_list.html

<tr>
    <th>idth>
    <th>usernameth>
    <th>emailth>
    <th>genderth>
    <th>options(<a th:href="@{/toAdd}">adda>)th>
tr>

由于添加操作不需要处理其他的业务逻辑,所以可以在springMVC.xml中使用view-controller标签去实现控制器功能。

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

创建user_add.html

DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8" xmlns:th="http://www.thymeleaf.org">
    <title>add usertitle>
head>
<body>
<form th:action="@{/user}" method="post">
  username:<input type="text" name="username"><br/>
  email:<input type="text" name="email"><br/>
  gender:<input type="radio" name="gender" value="1">male
  <input type="radio" name="gender" value="0">female<br/>
  <input type="submit" value="add">
form>
body>
html>

控制器

@RequestMapping(value = "/user", method = RequestMethod.POST)
public String addUser(User user){
   userDao.save(user);
   return "redirect:/user";
}

测试

在这里插入图片描述

RESTful_第6张图片

⑤更新操作

更新操作和删除操作类似,但是需要表单显示相关内容并提交(回显)。

user_list.html

<a th:href="@{'/user/' + ${user.id}}">updatea>

控制器

@RequestMapping(value = "/user/{id}", method = RequestMethod.GET)
/*需要通过id查询数据,同时还需要将查询出来的数据在域中实现共享*/
public String getUserById(@PathVariable("id") Integer id, Model model){
    User user = userDao.get(id);
    model.addAttribute("user", user);
    return "user_update";
}

创建user_update.html实现回显

DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8" xmlns:th="http://www.thymeleaf.org">
    <title>add usertitle>
head>
<body>

<form th:action="@{/user}" method="post">
    <input type="hidden" name="_method" value="put">
    <input type="hidden" name="id" th:value="${user.id}">
  username:<input type="text" name="username" th:value="${user.username}"><br/>
  email:<input type="text" name="email" th:value="${user.email}"><br/>
  gender:<input type="radio" name="gender" value="1" th:field="${user.gender}">male
  <input type="radio" name="gender" value="0" th:field="${user.gender}">female<br/>
  <input type="submit" value="update">
form>
body>
html>

在这里插入图片描述

创建修改的控制器

@RequestMapping(value = "/user", method = RequestMethod.PUT)
public String updateUser(User user){
    userDao.save(user);
    return "redirect:/user";
}

测试

在这里插入图片描述

在这里插入图片描述

你可能感兴趣的:(springMVC,restful,后端,java)