[SpringMVC] | RESTful architecture style, RESTful case (CRUD)

Table of contents 

RESTful architectural style

1. Introduction to RESTful

2. Implementation of RESTful

3. HiddenHttpMethodFilter

RESTful case (CRUD)

1. Preparations

2. Feature List

List function (display data) 

Delete data (difficulty)

adding data 

update data

Book recommendation: use ChatGPT and VBA to get Excel with one click


RESTful architectural style

1. Introduction to RESTful

REST: Re presentational State Transfer , resource state transfer at the presentation layer.

a> resources

        A resource is a way of looking at a server, that is, as consisting of many discrete resources. Each resource is a nameable abstraction on the server. Because a resource is an abstract concept, it can not only represent a file in the server file system, a table in the database, and other specific things. You can design resources as abstract as your imagination allows. And client application developers can understand. Similar to object-oriented design, resources are organized around nouns , with the nouns being the first focus. A resource can be identified by one or more URIs. A URI is both the name of a resource and its address on the Web . A client application interested in a resource can interact with it through the resource's URI.

b>Representation of resources

        A resource representation is a description of the state of the resource at a particular moment. Can be transferred (swapped) between client-server. Resource representations can be in multiple formats, for example: HTML/XML/JSON/plain text/picture/video/audio and so on. The representation format of resources can be determined through a negotiation mechanism. The representation of the request-response direction usually uses a different format.

c> state transition

        State transfer refers to the transfer (transfer) between the client and the server to represent the representation of the state of the resource . Through the expression of transferring and operating resources, the purpose of operating resources is indirectly realized.

2. Implementation of RESTful

(1) Specifically, in the HTTP protocol, there are four verbs indicating the operation mode: GET, POST, PUT, DELETE. They correspond to four basic operations: GET is used to obtain resources , POST is used to create new resources , PUT is used to update resources , and DELETE is used to delete resources .

(2) The REST style advocates the use of a unified style design for the URL address . From the front to the back, each word is separated by a slash ( the front end is a bar and a value, and the back end is a bar and a curly brace ), and the request is not carried in the form of question mark key-value pairs. Parameters , but the data to be sent to the server as part of the URL address to ensure the consistency of the overall style.

operate traditional way REST style
query operation getUserById?id=1 user/1-->get request method
save operation saveUser user-->post request method
delete operation deleteUser?id=1 user/1-->delete request method
update operation updateUser user-->put request method

3. HiddenHttpMethodFilter

(1) Since the browser only supports sending get and post requests, how to send put and delete requests? SpringMVC provides HiddenHttpMethodFilter to help us convert POST requests into DELETE or PUT requests!

(2) HiddenHttpMethodFilter processes the conditions for put and delete requests :

①The request method of the current request must be: post ;

②The current request must transmit request parameters: _method ( this parameter has three values: put, delete, patch ) .

(3) If the above conditions are met, the HiddenHttpMethodFilter filter will convert the request method of the current request into the value of the request parameter _method, so the value of the request parameter _method is the final request method.

Register HiddenHttpMethodFilter  in web.xml

    <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>

Note: So far, SpringMVC has provided two filters: CharacterEncodingFilter and HiddenHttpMethodFilter When registering in web.xml , you must first register CharacterEncodingFilter, and then register HiddenHttpMethodFilter.

Reason: The character set is set through the request.setCharacterEncoding(encoding) method in CharacterEncodingFilter; the request.setCharacterEncoding(encoding) method requires no previous operations to obtain request parameters; and HiddenHttpMethodFilter has exactly one operation to obtain request methods:

String paramValue = request.getParameter(this.methodParam);

Send Get, Post, Put, Delete request practical operation

The front end sends a request:

<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
<!--发送Get请求-->
<a th:href="@{/user}">查询所有用户信息</a><br>
<a th:href="@{/user/1}">根据id查询用户信息</a><br>
<!--发送Post请求-->
<form th:action="@{/user}" method="post">
    用户:<input type="text" name="username"><br>
    密码:<input type="password" name="password"><br>
    <input type="submit" name="Post提交"><br>
</form>

<!--发送put请求-->
<form th:action="@{/user}" method="post">
    <!--设置隐藏域的请求类型-->
    <input type="hidden" name="_method" value="put"><br>
    用户:<input type="text" name="username"><br>
    密码:<input type="password" name="password"><br>
    <input type="submit" name="Put提交"><br>
</form>
<!--发送delete请求-->
<form th:action="@{/user/2}" method="post">
    <input type="hidden" name="_method" value="delete"><br>
    <input type="submit" name="Delete提交"><br>
</form>
</body>
</html>

The backend receives the request:

Note: Hyperlinks are generally used when performing delete operations, but they are generally associated with Vue or ajax; here is the form of the form form, but when using the form form to perform delete operations, the @RequestMappping annotation cannot be used, and then the method attribute To specify the method of request (error will be reported). Just use the derived annotation @DeleteMapping directly

package com.zl.controller;

import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;

/**
 * 使用Restful模拟用户资源的增删改查
 * /user    Get     查询所有用户信息
 * /user/1  Get     根据用户id查询用户信息
 * /user    Post    添加用户信息
 * /user/1  Delete  根据用户id删除用户信息
 * /user    Put     修改用户信息
 */
@Controller
public class UserController {
    @RequestMapping("/")
    public String forwardIndex(){
        return "index";
    }

    // 发送Get查询所有
    @RequestMapping(value = "/user",method = RequestMethod.GET)
    public String getAllUser(){
        System.out.println("查询所有用户信息");
        return "success";
    }
    // 发送Get查询一个
    @RequestMapping(value = "/user/{id}",method = RequestMethod.GET)
    public String getUserById(@PathVariable String id){
        System.out.println("根据用户id查询用户信息"+id);
        return "success";
    }
    // 发送Post增加
    @RequestMapping(value = "/user",method = RequestMethod.POST)
    public String insertUser(String username,String password){
        System.out.println("成功添加用户:"+username+"密码是:"+password);
        return "success";
    }

    // 发送put修改
    @RequestMapping(value = "/user",method = RequestMethod.PUT)
    public String putUser(){
        System.out.println("修改用户信息");
        return "success";
    }

    // 发送Delete删除
    // @RequestMapping(value = "/user/{id}}",method = RequestMethod.DELETE)
    @DeleteMapping(value = "/user/{id}")
    public String deleteUserById(@PathVariable String id){
        System.out.println("根据用户id删除用户信息:"+id);
        return "success";
    }
}

RESTful case (CRUD)

1. Preparations

build environment

pom.xml

<?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>org.example</groupId>
  <artifactId>springmvc-thymeleaf-restful</artifactId>
  <version>1.0-SNAPSHOT</version>
  <packaging>war</packaging>

  <name>springmvc-thymeleaf-restful Maven Webapp</name>
  <!-- FIXME change it to the project's website -->
  <url>http://www.example.com</url>

  <properties>
    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    <maven.compiler.source>1.8</maven.compiler.source>
    <maven.compiler.target>1.8</maven.compiler.target>
  </properties>

  <dependencies>
    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-webmvc</artifactId>
      <version>5.2.5.RELEASE</version>
    </dependency>
    <dependency>
      <groupId>javax.servlet</groupId>
      <artifactId>javax.servlet-api</artifactId>
      <version>3.1.0</version>
    </dependency>
    <dependency>
      <groupId>org.thymeleaf</groupId>
      <artifactId>thymeleaf-spring5</artifactId>
      <version>3.0.10.RELEASE</version>
    </dependency>
    <dependency>
      <groupId>ch.qos.logback</groupId>
      <artifactId>logback-classic</artifactId>
      <version>1.2.3</version>
    </dependency>
  </dependencies>

  <!--指定资源文件的位置-->
  <build>
    <resources>
      <resource>
        <directory>src/main/java</directory>
        <includes>
          <include>**/*.xml</include>
          <include>**/*.properties</include>
        </includes>
      </resource>
      <resource>
        <directory>src/main/resources</directory>
        <includes>
          <include>**/*.xml</include>
          <include>**/*.properties</include>
        </includes>
      </resource>
    </resources>
  </build>

</project>

web.xml 

<?xml version="1.0" encoding="UTF-8"?>
<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">
    <!--注册过滤器:解决post请求乱码问题-->
    <filter>
        <filter-name>encode</filter-name>
        <filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>
        <!--指定字符集-->
        <init-param>
            <param-name>encoding</param-name>
            <param-value>utf-8</param-value>
        </init-param>
        <!--强制request使用字符集encoding-->
        <init-param>
            <param-name>forceRequestEncoding</param-name>
            <param-value>true</param-value>
        </init-param>
        <!--强制response使用字符集encoding-->
        <init-param>
            <param-name>forceResponseEncoding</param-name>
            <param-value>true</param-value>
        </init-param>
    </filter>
    <!--所有请求-->
    <filter-mapping>
        <filter-name>encode</filter-name>
        <url-pattern>/*</url-pattern>
    </filter-mapping>

    <!--发送put、delete请求方式的过滤器-->
    <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>

    <!--注册SpringMVC框架-->
    <servlet>
        <servlet-name>springmvc</servlet-name>
        <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
        <!--配置springMVC位置文件的位置和名称-->
        <init-param>
            <param-name>contextConfigLocation</param-name>
            <param-value>classpath:springmvc.xml</param-value>
        </init-param>
        <!--将前端控制器DispatcherServlet的初始化时间提前到服务器启动时-->
        <load-on-startup>1</load-on-startup>
    </servlet>
    <servlet-mapping>
        <servlet-name>springmvc</servlet-name>
        <!--指定拦截什么样的请求
            例如:http://localhost:8080/demo.action
        -->
        <url-pattern>/</url-pattern>
    </servlet-mapping>
</web-app>

springmvc.xml

<?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/mvc https://www.springframework.org/schema/mvc/spring-mvc.xsd">
    <!--配置包扫描-->
    <context:component-scan base-package="com.zl"/>
    <!--视图控制器,用来访问首页;需要搭配注解驱动使用-->
    <mvc:view-controller path="/" view-name="index"/>
    <!--专门处理ajax请求,ajax请求不需要视图解析器InternalResourceViewResolver-->
    <!--但是需要添加注解驱动,专门用来解析@ResponseBody注解的-->
    <!--注入date类型时,需要使用@DateTimeFormat注解,也要搭配这个使用-->
    <mvc:annotation-driven/>

    <!-- 配置Thymeleaf视图解析器 -->
    <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>

Prepare Entity Class

package com.zl.bean;

public class Employee {
    private Integer id;
    private String lastName;
    private String email;
    private Integer gender;

    @Override
    public String toString() {
        return "Employee{" +
                "id=" + id +
                ", lastName='" + lastName + '\'' +
                ", email='" + email + '\'' +
                ", gender=" + 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() {
    }
}

Prepare dao simulation data: use the operation simulation of the Map collection to connect to the database

package com.zl.dao;

import com.zl.bean.Employee;
import org.springframework.stereotype.Repository;

import java.util.Collection;
import java.util.HashMap;
import java.util.Map;


@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){
        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);
    }
}

2.  Feature list

Function URL address request method
Visit homepage√ / GET
Query all data√ /employee GET
Delete √ /employee/2 DELETE
Jump to add data page√ /toAdd GET
Execute save√ /employee POST
Jump to update data page√ /employee/2 GET
Perform update√ /employee PUT

List function (display data) 

index.html: Send a request to query all employees

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

</body>
</html>

EmployeeController: Receive the request, get the data and put it in the domain object; and jump to the page to display the data

package com.zl.controller;

import com.zl.bean.Employee;
import com.zl.dao.EmployeeDao;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.ResponseBody;

import java.util.Collection;
import java.util.Iterator;


@Controller
public class EmployeeController {

    @Autowired
    private EmployeeDao employeeDao;

    // 查看员工信息
    @GetMapping("/employee")
    public String getEmployees(Model model){
        Collection<Employee> employees = employeeDao.getAll();
        System.out.println(employees);
        // 放到域对象当中
        model.addAttribute("employees",employees);
        // 跳转页面进行数据的展示
        return "employee_list";
    }

}

employee_list.html: display data

① Two important tags in the front end are from and table: from is used to send requests, and table is used to display data. The border attribute means to set the border, cellpadding and cellspacing means to set the margin and spacing of the border to 0, and the style is used to set the centering operation (you can also directly use align="center").

② Use thymeleaf to facilitate data, which is very similar to the use of the JSTL tag library, but the format is different; this uses the each tag of thymeleaf, and the format is: "Custom variable name: the key to put in the domain object data"

<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
    <meta charset="UTF-8">
    <title>Employee Info</title>
</head>
<body>
<!--表格展示数据:居中、边框的边距和间距设为0-->
<table border="1" style="text-align: center" cellpadding="0" cellspacing="0" >
    <tr>
        <!--colspan合并单元格,表示当前字段占用5个单元格-->
        <th colspan="5">Employee Info</th>
    </tr>
    <tr>
        <th>id</th>
        <th>lastName</th>
        <th>email</th>
        <th>gender</th>
        <th>options</th>
    </tr>
    <!--使用thymeleaf遍历数据,类似于JSTL标签库-->
    <tr th:each="employee : ${employees}">
        <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 href="">delete</a>
            <a href="">update</a>
        </td>
    </tr>
</table>

</body>
</html>

Show results:

Delete data (difficulty)

Question: Does the delete operation handle hyperlink addresses?

The deletion operation is performed through the id, but the id at this time needs to be obtained dynamically, and cannot be hardcoded!

<a th:href="@{/employee/${employee.id}}">delete</a>

If you directly use ${employee.id} to add it after the path, the braces {} will be parsed by thymeleaf!

Solution 1: Use the + sign to splice and splice outside @{}, so that it will not be parsed by thymeleaf

<!--放到@{}外面,此时的 加号+ 会报错,但不影响使用-->
<a th:href="@{/employee/}+${employee.id}">delete</a>

Solution 2: It can also be spliced ​​in @{}, at this time the path /employee/ needs to be added with single quotes

<!--加上单引号的表示会被当做路径解析,后面的则会被当做数据解析-->
<a th:href="@{'/employee/'+${employee.id}}">delete</a>

Question: Control form submission via hyperlink?

Realize hyperlink control form form submission through Vue!

Note: Import the vue.js library under webapp/static/js!

① First, you need to create Vue and bind the container in Vue; we need to operate hyperlinks, so the bound elements must include the elements we want to operate. So you can define an id in the tr or table tag for binding.

②Set the click event of the hyperlink, use @click to bind a click event in the deleted hyperlink; then process the binding event in Vue's methods.

③Get the form form, so you need to set the id for the from form and get it. After the form is obtained, assign the href attribute of the hyperlink that triggers the event to the action of the form, submit the form, and cancel the default behavior of the hyperlink.

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

</head>
<body>
<!--表格展示数据:居中、边框的边距和间距设为0-->
<table id="dataTable" border="1" style="text-align: center" cellpadding="0" cellspacing="0" >
    <tr>
        <!--colspan合并单元格,表示当前字段占用5个单元格-->
        <th colspan="5">Employee Info</th>
    </tr>
    <tr>
        <th>id</th>
        <th>lastName</th>
        <th>email</th>
        <th>gender</th>
        <th>options</th>
    </tr>
    <!--使用thymeleaf遍历数据,类似于JSTL标签库-->
    <tr th:each="employee : ${employees}">
        <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>
            <!--删除操作,超链接控制form表单-->
            <a @click="deleteEmployee" th:href="@{'/employee/'+${employee.id}}">delete</a>
            <a href="">update</a>
        </td>
    </tr>
</table>

<!--表单-->
<form  id="deleteForm" method="post">
    <input type="hidden" name="_method" value="delete" />
</form>
<!--引入Vue-->
<script type="text/javascript" th:src="@{/static/js/vue.js}" />
<!--使用js代码-->
<script type="text/javascript">
    // 创建Vue
    var vue = new Vue({
        // 绑定容器(使用el属性)
        el:"#dataTable",
        // 处理绑定事件(使用methods属性)
        methods:{
        // 函数的名称和对应的函数
            deleteEmployee:function(event){ // event代表当前的点击事件
                // 根据id获取form表单元素
                var deleteForm = document.getElementById("deleteForm");
                // 将触发事件的超连接的href属性赋值给表单的action
                deleteForm.action = event.target.href;
                // 提交表单
                deleteForm.submit();
                // 取消超连接的默认行为
                event.preventDefault();

            }
        }
    });
</script>

</body>
</html>

delete by id

Note: At this time, you will encounter the problem of forwarding or redirecting; after deleting, it has nothing to do with the current page, it is to jump to another page, and the address in the address bar must also change, so use redirection!

    // 根据id删除员工
    @DeleteMapping("/employee/{id}")
    public String deleteEmployee(@PathVariable Integer id){
        employeeDao.delete(id);
        // 重定向到列表页面
        return "redirect:/employee";
    }

Question 1: Re-deploy to access at this time, and the browser will report an error at this time (the send is still a get request, and the bound event does not work)

F12 opens the debugging window and finds that vue.js cannot be found

 At this time, open the war package of the current project and find that there is no static directory

 Solution: Repackage

Question 2: The above is to solve the problem that the current project does not exist, so I can’t find it; after repackaging, the current server already has it, but I still can’t find it!

Explanation: At this time, it is caused by the front controller DispatcherServlet, because the processing path we set is "/", which means all paths except jsp. At this time, the static resource vue.js is processed by SpringMVC, but the static resource cannot be processed by SpringMVC. Spring MVC processing. At this time, a default-servlet-handler is needed to open access to static resources!

<!--开放对静态资源的访问-->
<mvc:default-servlet-handler />

How <mvc:default-servlet-handler /> works:

First, static resources will be processed by SpringMVC's front-end controller DispatcherServlet. If the corresponding request mapping cannot be found in the front-end controller, it will be handed over to the default Servlet for processing. If the default Servlet can find the resource, it will access the resource. , if not found, report 404!

Question 3: At this time, the browser may report an error

Explanation: You are running Vue in development mode. When deploying to production, make sure to turn on production mode.

Do it according to the prompt, just turn off the prompt of the production mode, that is, set it to false即可

<script>Vue.config.productionTip= false </script>

At this point, the delete operation can be performed normally 

adding data 

Write a hyperlink to jump to the added page

<th>options(<a th:href="@{/toAdd}">add</a>)</th>

No need for any business logic at this point, use the view controller

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

 employee_add to add data

<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
    <meta charset="UTF-8">
    <title>add employee</title>
</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>

Get the data submitted by the form form and add it

    // 添加数据
    @PostMapping("/employee")
    public String addEmployee(Employee employee){
        employeeDao.save(employee);
        // 重定向到列表页面
        return "redirect:/employee";
    }

Added successfully

update data

Modify according to id

<!--修改操作-->
<a th:href="@{'/employee/'+${employee.id}}">update</a>

Note: This involves a function of echoing data, so you need to jump to a Controller to query the data first, put the data in the domain object and then jump to a new page employee_update page display, through the data displayed on this page Modify, modify and submit after being processed by a Controller and rushed to the page display function page for data display!

Query data first according to id

   // 用户回显数据的controller
    @RequestMapping("/employee/{id}")
    public String getEmployeeById(@PathVariable Integer id,Model model){
        // 根据id查
        Employee employee = employeeDao.get(id);
        // 存到域对象当中
        model.addAttribute("employee",employee);
        // 跳转到回显数据的页面
        return "employee_update";
    }

employee_update that echoes data and can update data

For the echo of the single display box, the field attribute is used!

<!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">
    <!--发送put请求-->
    <input type="hidden" name="_method" value="put">
    <!--id也回显,设置为隐藏域,或者设置为只读-->
    <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>
    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>

Effect display: the effect of echoing data by default

Update the page that echoes the data above, store the data submitted according to the update, and then redirect to the list page for display

    // 更新数据的Controller
    @PutMapping("/employee")
    public String updateEmployee(Employee employee){
        // 更新数据
        employeeDao.save(employee);
        // 重定向到列表页面
        return "redirect:/employee";
    }

Book recommendation: use ChatGPT and VBA to get Excel with one click

way of participation:

1 book this time! 
Activity time: until 2023-06-15 00:00:00.

Lottery draw method: Use the program to draw a lottery.

Participation method: follow the blogger (only for fan benefits), like, bookmark, random selection in the comment area, up to three comments!

Books in this issue: "Using ChatGPT and VBA to Get Excel with One Click"

        Today, with the emergence of AIGC (AI Generated Content, using artificial intelligence technology to generate content) tools represented by ChatGPT, the threshold for learning programming has been greatly reduced. For most professionals who have no programming foundation, office automation programming languages ​​such as VBA are easier to master than ever before, which can greatly improve work efficiency. Through three parts: VBA basic knowledge, ChatGPT basic knowledge, and ChatGPT practical office automation, this book helps Excel users quickly master VBA from scratch, and flexibly respond to any scene that requires automated office in the way of "teaching people how to fish".

        In short, the goal of this book is: ordinary users only need to master some basic concepts of VBA, and then with the help of ChatGPT, they can get corresponding VBA codes to solve specific problems.

Jingdong purchase link: click to buy

Guess you like

Origin blog.csdn.net/m0_61933976/article/details/130956237