SpringMVC学习笔记之RESTful风格

文章目录

    • 7 使用SpringMVC完成RESTful的实现
      • 7.1 什么是RESTful风格?
      • 7.2 传统风格与RESTFul风格对比
        • 7.2.1 使用传统风格操作资源
        • 7.2.2 使用RESTful风格操作资源
      • 7.3 HiddenHttpMethodFilter
      • 7.4 RESTful案例
        • 7.4.1 准备工作
        • 7.4.2 功能清单
        • 7.4.3 具体功能:访问首页
        • 7.4.4 具体功能:查询所有员工数据
        • 7.4.5 具体功能:删除
        • 7.4.6 具体功能:添加数据
        • 7.4.7 具体功能:跳转到更新数据页面
        • 7.4.8 执行更新

7 使用SpringMVC完成RESTful的实现

7.1 什么是RESTful风格?

REST:Representational State Transfer,表现层资源状态转移。它就是一个资源定位、资源操作的风格。不是标准也不是协议,只是一种风格 。基于这个风格设计的软件可以更简洁,更有层次,更易于实现缓存等机制。

**资源的定义:**互联网所有的事物都可以被抽象为资源。
**状态转移:**在客户端和服务器端之间转移(transfer)代表资源状态的表述。通过转移和操作资源的表述,来间接实现操作资源的目的。
资源操作:分为POSTDELETEPUTGET四种方法,使用不同方法对资源进行操作(增、删、改、查)
SpringMVC学习笔记之RESTful风格_第1张图片

7.2 传统风格与RESTFul风格对比

7.2.1 使用传统风格操作资源

通过不同的参数来实现不同的效果!方法单一!

http://127.0.0.1/item/queryItem?id=1 (查询,GET)
http://127.0.0.1/item/saveItem (新增,POST)
http://127.0.0.1/item/updateItem (更新,POST)
http://127.0.0.1/item/deleteItem?id=1 (删除,GET或POST)

7.2.2 使用RESTful风格操作资源

可以通过不同的请求方式来实现不同的效果!
如下:请求地址一样,但是功能可以不同!

http://127.0.0.1/item/1 (查询,GET)
http://127.0.0.1/item (新增,POST)
http://127.0.0.1/item (更新,PUT)
http://127.0.0.1/item/1 (删除,DELETE)

7.3 HiddenHttpMethodFilter

由于浏览器只支持发送get和post方式的请求,那么该如何发送put和delete请求呢?

SpringMVC 提供了 HiddenHttpMethodFilter 帮助我们将 POST 请求转换为 DELETE 或 PUT 请求

HiddenHttpMethodFilter 处理put和delete请求的条件:

  • 当前请求的请求方式必须为post(通过表单或者ajax来发送post请求)

  • 当前请求必须传输请求参数_method

满足以上条件,HiddenHttpMethodFilter 过滤器就会将当前请求的请求方式转换为请求参数_method的值,因此请求参数_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>

注:
目前为止,SpringMVC中提供了两个过滤器:CharacterEncodingFilter和HiddenHttpMethodFilter
在web.xml中注册时,必须先注册CharacterEncodingFilter,再注册HiddenHttpMethodFilter
原因:

  • 在 CharacterEncodingFilter 中通过 request.setCharacterEncoding(encoding) 方法设置字符集的
  • request.setCharacterEncoding(encoding) 方法要求前面不能有任何获取请求参数的操作
  • 而 HiddenHttpMethodFilter 恰恰有一个获取请求方式的操作:
    String paramValue = request.getParameter(this.methodParam);

7.4 RESTful案例

案例目标:和传统 CRUD 一样,实现对员工信息的增删改查。

7.4.1 准备工作

  1. 搭建一个新的项目

  2. 准备实体类

    public class Employee {
    
       private Integer id;
       private String lastName;
    
       private String email;
       //1 male, 0 female
       private Integer gender;
       
       public Integer getId() {
          return id;
       }
    
       public void setId(Integer id) {
          this.id = id;
       }
    
       public String getLastName() {
          return lastName;
       }
    
       public void setLastName(String lastName) {
          this.lastName = lastName;
       }
    
       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;
       }
    
       public Employee(Integer id, String lastName, String email, Integer gender) {
          super();
          this.id = id;
          this.lastName = lastName;
          this.email = email;
          this.gender = gender;
       }
    
       public Employee() {
       }
    }
    
  3. 准备dao模拟数据

    import java.util.Collection;
    import java.util.HashMap;
    import java.util.Map;
    
    import com.zjw.mvc.bean.Employee;
    import org.springframework.stereotype.Repository;
    
    
    @Repository
    public class EmployeeDao {
    
       private static Map<Integer, Employee> employees = null;
       
       static{
          employees = new HashMap<Integer, Employee>();
    
          employees.put(1001, new Employee(1001, "E-AA", "[email protected]", 1));
          employees.put(1002, new Employee(1002, "E-BB", "[email protected]", 1));
          employees.put(1003, new Employee(1003, "E-CC", "[email protected]", 0));
          employees.put(1004, new Employee(1004, "E-DD", "[email protected]", 0));
          employees.put(1005, new Employee(1005, "E-EE", "[email protected]", 1));
       }
       
       private static Integer initId = 1006;
       
       public void save(Employee employee){
       //如果没有ID,则自动给它赋值
          if(employee.getId() == null){
             employee.setId(initId++);
          }
          employees.put(employee.getId(), employee);
       }
       
       public Collection<Employee> getAll(){
          return employees.values();
       }
       
       public Employee get(Integer id){
          return employees.get(id);
       }
       
       public void delete(Integer id){
          employees.remove(id);
       }
    }
    

7.4.2 功能清单

SpringMVC学习笔记之RESTful风格_第2张图片

7.4.3 具体功能:访问首页

  1. 配置view-controller

    <mvc:view-controller path="/" view-name="index"/>
    
  2. 创建页面

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

SpringMVC学习笔记之RESTful风格_第3张图片

7.4.4 具体功能:查询所有员工数据

  1. 控制器方法

    @RequestMapping(value = "/employee", method = RequestMethod.GET)
    public String getEmployeeList(Model model){
        Collection<Employee> employeeList = employeeDao.getAll();
        model.addAttribute("employeeList", employeeList);
        return "employee_list";
    }
    
  2. 创建employee_list.html

    DOCTYPE html>
    <html lang="en" xmlns:th="http://www.thymeleaf.org">
    <head>
        <meta charset="UTF-8">
        <title>Employee Infotitle>
        <script type="text/javascript" th:src="@{/static/js/vue.js}">script>
    head>
    <body>
    
        <table border="1" cellpadding="0" cellspacing="0" style="text-align: center;" id="dataTable">
            <tr>
                <th colspan="5">Employee Infoth>
            tr>
            <tr>
                <th>idth>
                <th>lastNameth>
                <th>emailth>
                <th>genderth>
                <th>options(<a th:href="@{/toAdd}">adda>)th>
            tr>
            <tr th:each="employee : ${employeeList}">
                <td th:text="${employee.id}">td>
                <td th:text="${employee.lastName}">td>
                <td th:text="${employee.email}">td>
                <td th:text="${employee.gender}">td>
                <td>
                    <a class="deleteA" @click="deleteEmployee" th:href="@{'/employee/'+${employee.id}}">deletea>
                    <a th:href="@{'/employee/'+${employee.id}}">updatea>
                td>
            tr>
        table>
    body>
    html>
    
  3. 结果展示:
    SpringMVC学习笔记之RESTful风格_第4张图片

7.4.5 具体功能:删除

  1. 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>
  1. 创建处理delete请求方式的表单

    <!-- 作用:通过超链接控制表单的提交,将post请求转换为delete请求 -->
    <form id="delete_form" method="post">
        <!-- HiddenHttpMethodFilter要求:必须传输_method请求参数,并且值为最终的请求方式 -->
        <input type="hidden" name="_method" value="delete"/>
    </form>
    
  2. 删除超链接绑定点击事件

    引入vue.js

    <script type="text/javascript" th:src="@{/static/js/vue.js}"></script>
    

    SpringMVC学习笔记之RESTful风格_第5张图片
    删除超链接

    <a class="deleteA" @click="deleteEmployee" th:href="@{'/employee/'+${employee.id}}">delete</a>
    

    通过vue处理点击事件

    <script type="text/javascript">
        var vue = new Vue({
            el:"#dataTable",
            methods:{
                //event表示当前事件
                deleteEmployee:function (event) {
                    //通过id获取表单标签
                    var delete_form = document.getElementById("delete_form");
                    //将触发事件的超链接的href属性为表单的action属性赋值
                    delete_form.action = event.target.href;
                    //提交表单
                    delete_form.submit();
                    //阻止超链接的默认跳转行为
                    event.preventDefault();
                }
            }
        });
    </script>
    
  3. 控制器方法

    @RequestMapping(value = "/employee/{id}", method = RequestMethod.DELETE)
    public String deleteEmployee(@PathVariable("id") Integer id){
        employeeDao.delete(id);
        return "redirect:/employee";
    }
    

7.4.6 具体功能:添加数据

  1. 配置view-controller

    <mvc:view-controller path="/toAdd" view-name="employee_add">mvc:view-controller>
    
  2. 创建添加用户页面employee_add.html

    DOCTYPE html>
    <html lang="en" xmlns:th="http://www.thymeleaf.org">
    <head>
        <meta charset="UTF-8">
        <title>Add Employeetitle>
    head>
    <body>
    
    <form th:action="@{/employee}" method="post">
        lastName:<input type="text" name="lastName"><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"><br>
    form>
    
    body>
    html>
    
  3. 控制器方法

    @RequestMapping(value = "/employee", method = RequestMethod.POST)
    public String addEmployee(Employee employee){
        employeeDao.save(employee);
        return "redirect:/employee";
    }
    

7.4.7 具体功能:跳转到更新数据页面

  1. 修改超链接
<a th:href="@{'/employee/'+${employee.id}}">update</a>
  1. 控制器方法
@RequestMapping(value = "/employee/{id}", method = RequestMethod.GET)
public String getEmployeeById(@PathVariable("id") Integer id, Model model){
    Employee employee = employeeDao.get(id);
    model.addAttribute("employee", employee);
    return "employee_update";
}
  1. 创建employee_update.html

    <!DOCTYPE html>
    <html lang="en" xmlns:th="http://www.thymeleaf.org">
    <head>
        <meta charset="UTF-8">
        <title>Update Employee</title>
    </head>
    <body>
    
    <form th:action="@{/employee}" method="post">
        <input type="hidden" name="_method" value="put">
        <input type="hidden" name="id" th:value="${employee.id}">
        lastName:<input type="text" name="lastName" th:value="${employee.lastName}"><br>
        email:<input type="text" name="email" th:value="${employee.email}"><br>
        <!--
            th:field="${employee.gender}"可用于单选框或复选框的回显
            若单选框的value和employee.gender的值一致,则添加checked="checked"属性
        -->
        gender:<input type="radio" name="gender" value="1" th:field="${employee.gender}">male
        <input type="radio" name="gender" value="0" th:field="${employee.gender}">female<br>
        <input type="submit" value="update"><br>
    </form>
    
    </body>
    </html>
    

7.4.8 执行更新

控制器方法

@RequestMapping(value = "/employee", method = RequestMethod.PUT)
public String updateEmployee(Employee employee){
    employeeDao.save(employee);
    return "redirect:/employee";
}

当然了对于处理指定请求方式的控制器方法,SpringMVC中提供了@RequestMapping的派生注解

处理get请求的映射–>@GetMapping

处理post请求的映射–>@PostMapping

处理put请求的映射–>@PutMapping

处理delete请求的映射–>@DeleteMapping

你可能感兴趣的:(SSM框架学习,restful,java,后端)