[SpringMVC from entry to actual combat tutorial] Chapter 6 SpringMVC RESTful support

Six, SpringMVC RESTful support

6.1 What is RESTful

  • The RESTful architecture is currently the most popular Internet software architecture. It has a clear structure, conforms to standards, is easy to understand, and is easy to expand, so it is being adopted by more and more websites.
  • RESTful (the abbreviation of Representational State Transfer) is actually a development concept and a good interpretation of http.

The concept of REST is relatively complicated, so we won't explain it too much. You can simply understand the simple use of Spring MVC's REST style.

6.1.1 Standardizing URLs

Features: The url is concise, and the parameters are passed to the server through the url.

The following example illustrates the difference between a RESTful URL and a traditional URL:

/userview.html?id=12	VS     /user/view/12
/userdelete.html?id=12	VS     /user/delete/12
/usermodify.html?id=12	VS     /user/modify/12
  • The most obvious thing we found with RESTful URLs is that parameters are no longer passed using "?". This style of URL is more readable and makes the project structure clear. The most important thing is that Spring MVC also provides support for this style.
  • But there are also disadvantages. For domestic projects, URL parameters sometimes pass Chinese, and Chinese garbled characters are a headache, so we should handle them flexibly according to the actual situation. Many websites use a mix of traditional URL style and REST style.

6.1.2 HTTP method specification

	Spring REST 风格可以简单理解为:使用 URL 表示资源时,每个资源都用一个独一无二的 URL 来表示,并使用 HTTP 方法表示操作,即准确描述服务器对资源的处理动作(GET、POST、PUT、DELETE),实现资源的增删改查。
	
	GET:表示获取资源。
    POST:表示新建资源。
    PUT:表示更新资源。
    DELETE:表示删除资源。
Function url path request method
Check all /emp/find GET
single check /emp/find/7369 GET
Add /emp/add POST
Revise /emp/edit PUT
delete /emp/remove/7369 DELETE

6.2 maven dependencies

<dependencies>
    <!-- spring核心包-->
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-core</artifactId>
        <version>4.3.18.RELEASE</version>
    </dependency>
    <!-- springbean包 -->
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-beans</artifactId>
        <version>4.3.18.RELEASE</version>
    </dependency>
    <!-- springcontext包 -->
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-context</artifactId>
        <version>4.3.18.RELEASE</version>
    </dependency>
    <!-- spring表达式包 -->
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-expression</artifactId>
        <version>4.3.18.RELEASE</version>
    </dependency>
    <!-- springAOP包 -->
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-aop</artifactId>
        <version>4.3.18.RELEASE</version>
    </dependency>
    <!-- springAspects包 -->
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-aspects</artifactId>
        <version>4.3.18.RELEASE</version>
    </dependency>
    <!-- spring对web的支持 -->
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-web</artifactId>
        <version>4.3.18.RELEASE</version>
    </dependency>
    <!-- springwebMVC -->
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-webmvc</artifactId>
        <version>4.3.18.RELEASE</version>
    </dependency>

    <!-- 配置javaweb环境 -->
    <!-- servlet-api -->
    <dependency>
        <groupId>javax.servlet</groupId>
        <artifactId>javax.servlet-api</artifactId>
        <version>3.1.0</version>
        <scope>provided</scope>
    </dependency>
    <!-- jsp-api -->
    <dependency>
        <groupId>javax.servlet.jsp</groupId>
        <artifactId>jsp-api</artifactId>
        <version>2.1</version>
        <scope>provided</scope>
    </dependency>
    <!-- jstl -->
    <dependency>
        <groupId>javax.servlet</groupId>
        <artifactId>jstl</artifactId>
        <version>1.2</version>
    </dependency>

    <!-- jackson -->
    <dependency>
        <groupId>com.fasterxml.jackson.core</groupId>
        <artifactId>jackson-core</artifactId>
        <version>2.9.5</version>
    </dependency>
    <dependency>
        <groupId>com.fasterxml.jackson.core</groupId>
        <artifactId>jackson-databind</artifactId>
        <version>2.9.5</version>
    </dependency>
    <dependency>
        <groupId>com.fasterxml.jackson.core</groupId>
        <artifactId>jackson-annotations</artifactId>
        <version>2.9.5</version>
    </dependency>
</dependencies>

6.3 web.xml

  • The configuration of the front controller needs to be modified to support the restful style.
  • Configure the character encoding filter that comes with spring.
<?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">

    <!-- Spring中自带的字符编码过滤器-->
    <filter>
        <filter-name>CharacterEncodingFilter</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>
    </filter>
    <filter-mapping>
        <filter-name>CharacterEncodingFilter</filter-name>
        <url-pattern>/*</url-pattern>
    </filter-mapping>

    <!-- 配置前端控制器 -->
    <servlet>
        <servlet-name>springmvc</servlet-name>
        <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
        <init-param>
            <param-name>contextConfigLocation</param-name>
            <param-value>classpath:springmvc.xml</param-value>
        </init-param>
        <load-on-startup>1</load-on-startup>
    </servlet>
    <servlet-mapping>
        <servlet-name>springmvc</servlet-name>
        <!--springmvc接收请求的路径修改为/,以支持restful风格-->
        <url-pattern>/</url-pattern>
    </servlet-mapping>

    <welcome-file-list>
        <welcome-file>/views/index.jsp</welcome-file>
    </welcome-file-list>
</web-app>

6.4 Spring MVC configuration

In the configuration of SpringMVC, it is necessary to add the processing of static resource access, otherwise the static resource will not be used normally.

<?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:p="http://www.springframework.org/schema/p"
        xmlns:context="http://www.springframework.org/schema/context"
        xmlns:aop="http://www.springframework.org/schema/aop"
        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
    http://www.springframework.org/schema/context/spring-context.xsd
    http://www.springframework.org/schema/aop
    http://www.springframework.org/schema/aop/spring-aop.xsd
    http://www.springframework.org/schema/mvc
    http://www.springframework.org/schema/mvc/spring-mvc.xsd">

    <!-- springmvc的注解式开发 -->
    <!-- 开启组件扫描 -->
    <context:component-scan base-package="com.newcapec"/>

    <!-- MVC注解驱动 -->
    <mvc:annotation-driven/>
    
    <!-- 配置视图解析器 -->
    <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
        <!-- 配置视图地址的前缀和后缀:简化视图地址 -->
        <property name="prefix" value="/views/"/>
        <property name="suffix" value=".jsp"/>
    </bean>

    <!--不拦截静态资源-->
    <mvc:default-servlet-handler/>
</beans>

6.4.1 <mvc:default-servlet-handler/>Labels

Configure the default Servlet processor so that DispatcherServlet does not intercept static resources, and returns the processing of static resources to the Web application server through the Spring MVC framework.

<!--不拦截静态资源-->
<mvc:default-servlet-handler/>

6.4.2 <mvc:resources/>Labels

  • Map the static resources, handle the static resources by the Spring MVC framework itself, and add some useful added value functions.
  • <mvc:resources/>Static resources are allowed to be placed anywhere, such as under the WEB-INF directory, under the class path, etc.
  • Specify the location of static resources through the location attribute, and you can use resource prefixes such as "classpath:" to specify resource locations.
  • Static resources of traditional web containers can only be placed under the root path of the web container, which <mvc:resources />completely breaks this limitation.
<mvc:resources location="/js/" mapping="/js/**"/>
<mvc:resources location="/img/" mapping="/img/**"/>
<!--
	静态资源路径的映射
	WEB-INF目录为JavaWeb项目中的安全目录(不能直接访问的目录)
	1、动态页面:jsp和模板引擎页面,可以通过controller跳转,便于控制
	2、静态资源:.js,.css,图片,音频和视频等资源
-->
<mvc:resources location="/WEB-INF/static/images/" mapping="/images/**"/>
<mvc:resources location="classpath:/META-INF/publicResources/" mapping="/resources/**"/>

6.5 Use of REST in synchronous requests

6.5.1 Entity classes

public class User {
    
    
    
    private Integer userid;
    private String username;
    private String password;
    private String realname;

    public User() {
    
    
    }

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

    public Integer getUserid() {
    
    
        return userid;
    }

    public void setUserid(Integer userid) {
    
    
        this.userid = userid;
    }

    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 String getRealname() {
    
    
        return realname;
    }

    public void setRealname(String realname) {
    
    
        this.realname = realname;
    }
}

6.5.2 dao

interface:

public interface UserDao {
    
    

    void insert(User user);

    void update(User user);

    void delete(Integer id);

    User selectById(Integer id);

    List<User> select();
}

Implementation class:

@Repository("userDao")
public class UserDaoImpl implements UserDao {
    
    

    private static TreeMap<Integer, User> data = new TreeMap<>();
    
    static{
    
    
        User u1 = new User(1, "zhangsan", "123", "张三");
        User u2 = new User(2, "lisi", "111", "李四");
        User u3 = new User(3, "wangwu", "321", "王五");
        data.put(u1.getUserid(), u1);
        data.put(u2.getUserid(), u2);
        data.put(u3.getUserid(), u3);
    }

    @Override
    public void insert(User user) {
    
    
        user.setUserid(data.lastKey() + 1);
        data.put(user.getUserid(), user);
    }

    @Override
    public void update(User user) {
    
    
        data.put(user.getUserid(), user);
    }

    @Override
    public void delete(Integer id) {
    
    
        data.remove(id);
    }

    @Override
    public User selectById(Integer id) {
    
    
        return data.get(id);
    }

    @Override
    public List<User> select() {
    
    
        return new ArrayList<>(data.values());
    }
}

6.5.3 service

interface:

public interface UserService {
    
    

    void add(User user);

    void edit(User user);

    void remove(Integer id);

    User findById(Integer id);

    List<User> find();
}

Implementation class:

@Service("userService")
public class UserServiceImpl implements UserService {
    
    

    @Autowired
    private UserDao userDao;

    @Override
    public void add(User user) {
    
    
        userDao.insert(user);
    }

    @Override
    public void edit(User user) {
    
    
        userDao.update(user);
    }

    @Override
    public void remove(Integer id) {
    
    
        userDao.delete(id);
    }

    @Override
    public User findById(Integer id) {
    
    
        return userDao.selectById(id);
    }

    @Override
    public List<User> find() {
    
    
        return userDao.select();
    }
}

6.5.4 controller

/**
 * springmvc对rest风格的支持:同步请求
 */
@Controller
@RequestMapping("/user")
public class UserController {
    
    

    @Autowired
    private UserService userService;

    @RequestMapping(value = "/find", method = RequestMethod.GET)
    public String find(Model model) {
    
    
        List<User> list = userService.find();
        model.addAttribute("userList", list);
        return "user";
    }

    @RequestMapping(value = "/add", method = RequestMethod.POST)
    public String add(User user) {
    
    
        userService.add(user);
        return "redirect:/user/find";
    }

    /**
     * /user/remove/{id} 表示路径由/user/remove/和一个动态值组成
     * 获取路径的动态值:
     *
     * @PathVariable 位置:形参
     * 作用:从路径中获取请求参数数据
     * 属性:value指定路径的变量名与形参名绑定,路径中的变量名与形参名称一致时,可省略此属性
     */
    @RequestMapping(value = "/remove/{id}", method = RequestMethod.DELETE)
    public String remove(@PathVariable Integer id) {
    
    
        userService.remove(id);
        return "redirect:/user/find";
    }

    @RequestMapping(value = "/edit", method = RequestMethod.PUT)
    public String edit(User user) {
    
    
        userService.edit(user);
        return "redirect:/user/find";
    }

    @RequestMapping(value = "/find/{id}", method = RequestMethod.GET)
    public String findById(@PathVariable Integer id, Model model) {
    
    
        User user = userService.findById(id);
        model.addAttribute("user", user);
        return "user_edit";
    }
}

6.5.5 Pages

index.jsp:

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <base href="${pageContext.request.contextPath}/">
    <title>Title</title>
</head>
<body>
    <div style="text-align: center">
        <h1>首页</h1>
        <p><a href="user/find">用户列表</a></p>
        <p><a href="views/emp.jsp">员工列表</a></p>
    </div>
</body>
</html>

user.jsp:

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<html>
<head>
    <base href="${pageContext.request.contextPath}/">
    <title>Title</title>
    <link rel="stylesheet" href="bootstrap/css/bootstrap.min.css">
    <script type="text/javascript" src="js/jquery-3.3.1.min.js"></script>
    <script type="text/javascript" src="bootstrap/js/bootstrap.min.js"></script>
    <script type="text/javascript">
        function deleteUser(url) {
      
      
            if(confirm('确定要删除吗?')){
      
      
                var form = $('#deleteForm')[0];
                form.action = url;
                form.submit();
            }
        }
    </script>
</head>
<body>
    <div style="text-align: center;" class="container">
        <h1>用户信息</h1>
        <a href="views/user_add.jsp" class="btn btn-default">新增用户</a>
        <table class="table table-bordered table-hover table-striped">
            <tr>
                <th>编号</th>
                <th>用户名</th>
                <th>密码</th>
                <th>真实姓名</th>
                <th>操作</th>
            </tr>
            <c:forEach items="${userList}" var="user">
            <tr>
                <td>${user.userid}</td>
                <td>${user.username}</td>
                <td>${user.password}</td>
                <td>${user.realname}</td>
                <td>
                    <a href="user/find/${user.userid}" class="btn btn-default">编辑</a>&emsp;
                    <a href="javascript:deleteUser('user/remove/${user.userid}')" class="btn btn-danger">删除</a>
                </td>
            </tr>
            </c:forEach>
        </table>
    </div>
    <form id="deleteForm" method="post">
        <input type="hidden" name="_method" value="delete">
    </form>
</body>
</html>

user_add.jsp:

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <base href="${pageContext.request.contextPath}/">
    <title>Title</title>
    <link rel="stylesheet" href="bootstrap/css/bootstrap.min.css">
    <script type="text/javascript" src="js/jquery-3.3.1.min.js"></script>
    <script type="text/javascript" src="bootstrap/js/bootstrap.min.js"></script>
</head>
<body>
    <div style="text-align: center;" class="container">
        <h1>用户新增</h1>
        <form action="user/add" method="post" class="form-horizontal">
            <div class="form-group">
                <label class="control-label col-sm-2">用户名</label>
                <div class="col-sm-10">
                    <input type="text" class="form-control" name="username" placeholder="用户名">
                </div>
            </div>
            <div class="form-group">
                <label class="control-label col-sm-2">密码</label>
                <div class="col-sm-10">
                    <input type="password" class="form-control" name="password" placeholder="密码">
                </div>
            </div>
            <div class="form-group">
                <label class="control-label col-sm-2">真实姓名</label>
                <div class="col-sm-10">
                    <input type="text" class="form-control" name="realname" placeholder="真实姓名">
                </div>
            </div>
            <div class="form-group">
                <button type="submit" class="btn btn-primary">确定</button>
                <button type="reset" class="btn btn-default">取消</button>
            </div>
        </form>
    </div>
</body>
</html>

user_edit.jsp:

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <base href="${pageContext.request.contextPath}/">
    <title>Title</title>
    <link rel="stylesheet" href="bootstrap/css/bootstrap.min.css">
    <script type="text/javascript" src="js/jquery-3.3.1.min.js"></script>
    <script type="text/javascript" src="bootstrap/js/bootstrap.min.js"></script>
</head>
<body>
    <div style="text-align: center;" class="container">
        <h1>用户编辑</h1>
        <!--
        在同步请求中,如果需要发出put方式的请求
        1.配置HiddenHttpMethodFilter过滤器
        2.form表单的method属性值为post
        3.在form表单中通过隐藏域的方式来修改请求方式
            name="_method" value="put" -- 伪装put请求
            name="_method" value="delete" -- 伪装delete请求
        -->
        <form action="user/edit" method="post" class="form-horizontal">
            <input type="hidden" name="_method" value="put">
            <input type="hidden" name="userid" value="${user.userid}">
            <div class="form-group">
                <label class="control-label col-sm-2">用户名</label>
                <div class="col-sm-10">
                    <input type="text" class="form-control" name="username" placeholder="用户名" value="${user.username}">
                </div>
            </div>
            <div class="form-group">
                <label class="control-label col-sm-2">密码</label>
                <div class="col-sm-10">
                    <input type="password" class="form-control" name="password" placeholder="密码" value="${user.password}">
                </div>
            </div>
            <div class="form-group">
                <label class="control-label col-sm-2">真实姓名</label>
                <div class="col-sm-10">
                    <input type="text" class="form-control" name="realname" placeholder="真实姓名" value="${user.realname}">
                </div>
            </div>
            <div class="form-group">
                <button type="submit" class="btn btn-primary">确定</button>
                <button type="reset" class="btn btn-default">取消</button>
            </div>
        </form>
    </div>
</body>
</html>

6.5.6 PUT and DELETE requests in synchronization

	在同步请求中,因为form标签的method属性仅支持get/post值,是无法发出非get或post请求,所以需要通过表单隐藏域组件传参,以及配置过滤器的方式,来解决form表单的PUT与DELETE请求。
  • The following hidden field components need to be added to the form;
<input type="hidden" name="_method" value="put">
  • Configure filters;
<!-- 通过隐藏域传参解决form表单的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>

6.6 Use of REST in asynchronous requests

6.6.1 Entity classes

public class Emp {
    
    
    
    private Integer empno;
    private String ename;
    private String job;
    private Double sal;
    @JsonFormat(pattern = "yyyy-MM-dd", timezone = "GMT+8")
    @DateTimeFormat(pattern = "yyyy-MM-dd")
    private Date hiredate;

    public Emp() {
    
    
    }

    public Emp(Integer empno, String ename, String job, Double sal, Date hiredate) {
    
    
        this.empno = empno;
        this.ename = ename;
        this.job = job;
        this.sal = sal;
        this.hiredate = hiredate;
    }

    public Integer getEmpno() {
    
    
        return empno;
    }

    public void setEmpno(Integer empno) {
    
    
        this.empno = empno;
    }

    public String getEname() {
    
    
        return ename;
    }

    public void setEname(String ename) {
    
    
        this.ename = ename;
    }

    public String getJob() {
    
    
        return job;
    }

    public void setJob(String job) {
    
    
        this.job = job;
    }

    public Double getSal() {
    
    
        return sal;
    }

    public void setSal(Double sal) {
    
    
        this.sal = sal;
    }

    public Date getHiredate() {
    
    
        return hiredate;
    }

    public void setHiredate(Date hiredate) {
    
    
        this.hiredate = hiredate;
    }
}

6.6.2 dao

interface:

public interface EmpDao {
    
    
    
    void insert(Emp emp);

    void update(Emp emp);

    void delete(Integer empno);

    Emp selectById(Integer empno);

    List<Emp> select();
}

Implementation class:

@Repository("empDao")
public class EmpDaoImpl implements EmpDao {
    
    
    
    private static TreeMap<Integer, Emp> data = new TreeMap<>();

    static {
    
    
        Emp emp1 = new Emp(1001, "小刘", "职员", 3690.0, new Date());
        Emp emp2 = new Emp(1002, "小李", "经理", 6580.0, new Date());
        Emp emp3 = new Emp(1003, "小王", "职员", 4560.0, new Date());
        Emp emp4 = new Emp(1004, "小赵", "秘书", 4830.0, new Date());
        Emp emp5 = new Emp(1005, "小明", "职员", 3200.0, new Date());
        data.put(emp1.getEmpno(), emp1);
        data.put(emp2.getEmpno(), emp2);
        data.put(emp3.getEmpno(), emp3);
        data.put(emp4.getEmpno(), emp4);
        data.put(emp5.getEmpno(), emp5);
    }

    @Override
    public void insert(Emp emp) {
    
    
        emp.setEmpno(data.lastKey() + 1);
        data.put(emp.getEmpno(), emp);
    }

    @Override
    public void update(Emp emp) {
    
    
        data.put(emp.getEmpno(), emp);
    }

    @Override
    public void delete(Integer empno) {
    
    
        data.remove(empno);
    }

    @Override
    public Emp selectById(Integer empno) {
    
    
        return data.get(empno);
    }

    @Override
    public List<Emp> select() {
    
    
        return new ArrayList<>(data.values());
    }
}

6.6.3 service

interface:

public interface EmpService {
    
    

    void add(Emp emp);

    void edit(Emp emp);

    void remove(Integer id);

    Emp findById(Integer id);

    List<Emp> find();
}

Implementation class:

@Service("empService")
public class EmpServiceImpl implements EmpService {
    
    

    @Autowired
    private EmpDao empDao;

    @Override
    public void add(Emp emp) {
    
    
        empDao.insert(emp);
    }

    @Override
    public void edit(Emp emp) {
    
    
        empDao.update(emp);
    }

    @Override
    public void remove(Integer id) {
    
    
        empDao.delete(id);
    }

    @Override
    public Emp findById(Integer id) {
    
    
        return empDao.selectById(id);
    }

    @Override
    public List<Emp> find() {
    
    
        return empDao.select();
    }
}

6.6.4 controller

/**
 * springmvc对rest风格的支持:异步请求
 *
 * @ResponseBody 可以使用在处理类上,表示当前Controller类中所有的方法都带有@ResponseBody注解
 * 简化注解:
 * @RestController = @Controller + @ResponseBody
 */
//@Controller
//@ResponseBody
@RestController
@RequestMapping("/emp")
public class EmpController {
    
    

    @Autowired
    private EmpService empService;

    /**
     * 简化注解:
     * @GetMapping = @RequestMapping(method = RequestMethod.GET)
     */
    // @RequestMapping(value = "/find", method = RequestMethod.GET)
    @GetMapping("/find")
    public List<Emp> find() {
    
    
        return empService.find();
    }

    /**
     * 如果@ResponseBody注解方法的返回值为String类型,表示该返回值为响应客户端的数据
     * 注意:不会进行页面跳转,返回值不是逻辑视图名
     */
    @PostMapping("/add")
    public String add(@RequestBody Emp emp) {
    
    
        empService.add(emp);
        return "success";
    }

    @DeleteMapping("/remove/{id}")
    public String remove(@PathVariable Integer id) {
    
    
        empService.remove(id);
        return "success";
    }

    @PutMapping("/edit")
    public String edit(@RequestBody Emp emp) {
    
    
        empService.edit(emp);
        return "success";
    }

    @GetMapping("/find/{id}")
    public Emp findById(@PathVariable Integer id) {
    
    
        return empService.findById(id);
    }
}

6.6.5 Pages

emp.jsp:

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <base href="${pageContext.request.contextPath}/">
    <title>Title</title>
    <link rel="stylesheet" href="bootstrap/css/bootstrap.min.css">
    <script type="text/javascript" src="js/jquery-3.3.1.min.js"></script>
    <script type="text/javascript" src="bootstrap/js/bootstrap.min.js"></script>
    <script type="text/javascript">
        $(function () {
      
      
            findEmp();
        });

        function findEmp() {
      
      
            $.ajax('emp/find', {
      
      
                type: 'get',
                success: function (resp) {
      
      
                    var str = '';
                    $.each(resp, function () {
      
      
                        str += '<tr>';
                        str += '<td>' + this.empno + '</td>';
                        str += '<td>' + this.ename + '</td>';
                        str += '<td>' + this.job + '</td>';
                        str += '<td>' + this.sal + '</td>';
                        str += '<td>' + this.hiredate + '</td>';
                        str += '<td><a href="javascript:getEmp(' + this.empno + ')" class="btn btn-default">编辑</a>&emsp;<a href="javascript:removeEmp(' + this.empno + ')" class="btn btn-danger">删除</a></td>';
                        str += '</tr>';
                    });
                    $('#tab').html(str);
                }
            });
        }

        function addEmp() {
      
      
            $.ajax('emp/add', {
      
      
                type: 'post',
                data: JSON.stringify({
      
      
                    ename: $('#add_ename').val(),
                    job: $('#add_job').val(),
                    sal: $('#add_sal').val(),
                    hiredate: $('#add_hiredate').val()
                }),
                contentType: 'application/json',
                success: function (resp) {
      
      
                    if (resp == 'success') {
      
      
                        alert('新增成功');
                        $('#addWin').modal('hide');
                        $('#addForm')[0].reset();
                        findEmp();
                    }
                }
            });
        }

        function removeEmp(id) {
      
      
            if (confirm('确定要删除吗?')) {
      
      
                $.ajax('emp/remove/' + id, {
      
      
                    type: 'delete',
                    success: function (resp) {
      
      
                        if (resp == 'success') {
      
      
                            alert('删除成功');
                            findEmp();
                        }
                    }
                });
            }
        }

        function getEmp(id) {
      
      
            $.ajax('emp/find/' + id, {
      
      
                type: 'get',
                success: function (resp) {
      
      
                    $('#edit_empno').val(resp.empno);
                    $('#edit_ename').val(resp.ename);
                    $('#edit_job').val(resp.job);
                    $('#edit_sal').val(resp.sal);
                    $('#edit_hiredate').val(resp.hiredate);
                    $('#editWin').modal('show');
                }
            });
        }

        function editEmp() {
      
      
            $.ajax('emp/edit', {
      
      
                type: 'put',
                data: JSON.stringify({
      
      
                    empno: $('#edit_empno').val(),
                    ename: $('#edit_ename').val(),
                    job: $('#edit_job').val(),
                    sal: $('#edit_sal').val(),
                    hiredate: $('#edit_hiredate').val()
                }),
                contentType: 'application/json',
                success: function (resp) {
      
      
                    if (resp == 'success') {
      
      
                        alert('编辑成功');
                        $('#editWin').modal('hide');
                        $('#editForm')[0].reset();
                        findEmp();
                    }
                }
            });
        }
    </script>
</head>
<body>
<div style="text-align: center;" class="container">
    <a href="javascript:void(0);" class="btn btn-default" data-toggle="modal" data-target="#addWin">新增</a>
    <table class="table table-bordered table-hover table-striped">
        <thead>
        <tr>
            <th>员工编号</th>
            <th>员工姓名</th>
            <th>员工岗位</th>
            <th>员工薪资</th>
            <th>入职日期</th>
            <th>操作</th>
        </tr>
        </thead>
        <tbody id="tab"></tbody>
    </table>
</div>
<div id="addWin" class="modal fade">
    <div class="modal-dialog" role="document">
        <div class="modal-content">
            <div class="modal-header">
                <button type="button" class="close" data-dismiss="modal" aria-label="Close"><span aria-hidden="true">&times;</span>
                </button>
                <h4 class="modal-title">新增</h4>
            </div>
            <div class="modal-body">
                <form id="addForm" class="form-horizontal">
                    <div class="form-group">
                        <label class="control-label col-sm-2">员工姓名</label>
                        <div class="col-sm-10">
                            <input type="text" class="form-control" id="add_ename" placeholder="员工姓名">
                        </div>
                    </div>
                    <div class="form-group">
                        <label class="control-label col-sm-2">员工岗位</label>
                        <div class="col-sm-10">
                            <input type="text" class="form-control" id="add_job" placeholder="员工岗位">
                        </div>
                    </div>
                    <div class="form-group">
                        <label class="control-label col-sm-2">员工薪资</label>
                        <div class="col-sm-10">
                            <input type="text" class="form-control" id="add_sal" placeholder="员工薪资">
                        </div>
                    </div>
                    <div class="form-group">
                        <label class="control-label col-sm-2">入职日期</label>
                        <div class="col-sm-10">
                            <input type="date" class="form-control" id="add_hiredate" placeholder="入职日期">
                        </div>
                    </div>
                </form>
            </div>
            <div class="modal-footer">
                <button type="button" class="btn btn-default" data-dismiss="modal">取消</button>
                <button type="button" class="btn btn-primary" onclick="addEmp()">确定</button>
            </div>
        </div>
    </div>
</div>
<div id="editWin" class="modal fade">
    <div class="modal-dialog" role="document">
        <div class="modal-content">
            <div class="modal-header">
                <button type="button" class="close" data-dismiss="modal" aria-label="Close"><span aria-hidden="true">&times;</span>
                </button>
                <h4 class="modal-title">编辑</h4>
            </div>
            <div class="modal-body">
                <form id="editForm" class="form-horizontal">
                    <input type="hidden" id="edit_empno">
                    <div class="form-group">
                        <label class="control-label col-sm-2">员工姓名</label>
                        <div class="col-sm-10">
                            <input type="text" class="form-control" id="edit_ename" placeholder="员工姓名">
                        </div>
                    </div>
                    <div class="form-group">
                        <label class="control-label col-sm-2">员工岗位</label>
                        <div class="col-sm-10">
                            <input type="text" class="form-control" id="edit_job" placeholder="员工岗位">
                        </div>
                    </div>
                    <div class="form-group">
                        <label class="control-label col-sm-2">员工薪资</label>
                        <div class="col-sm-10">
                            <input type="text" class="form-control" id="edit_sal" placeholder="员工薪资">
                        </div>
                    </div>
                    <div class="form-group">
                        <label class="control-label col-sm-2">入职日期</label>
                        <div class="col-sm-10">
                            <input type="date" class="form-control" id="edit_hiredate" placeholder="入职日期">
                        </div>
                    </div>
                </form>
            </div>
            <div class="modal-footer">
                <button type="button" class="btn btn-default" data-dismiss="modal">取消</button>
                <button type="button" class="btn btn-primary" onclick="editEmp()">确定</button>
            </div>
        </div>
    </div>
</div>
</body>
</html>

6.6.6 Solve the problem of Put request parameter passing

	在异步请求中,可通过jQuery的ajax函数中type选项配置不同的请求方式,但真实put请求传递的数据SpringMVC无法接收,所以需要通过配置相应的过滤器来解决此问题。
<!-- 解决put请求传递参数的问题-->
<filter>
    <filter-name>HttpPutFormContentFilter</filter-name>
    <filter-class>org.springframework.web.filter.HttpPutFormContentFilter</filter-class>
</filter>
<filter-mapping>
    <filter-name>HttpPutFormContentFilter</filter-name>
    <url-pattern>/*</url-pattern>
</filter-mapping>

Guess you like

Origin blog.csdn.net/ligonglanyuan/article/details/125318741