【SpringMVC从入门到实战教程】第六章 SpringMVC RESTful支持

六、SpringMVC RESTful支持

6.1 什么是RESTful

  • RESTful架构,就是目前最流行的一种互联网软件架构。它结构清晰、符合标准、易于理解、扩展方便,所以正得到越来越多网站的采用。
  • RESTful(即Representational State Transfer的缩写)其实是一个开发理念,是对http的很好的诠释。

REST 概念较为复杂,我们不过多解释,大家简单了解 Spring MVC 的 REST 风格的简单使用即可。

6.1.1 对url进行规范

特点:url简洁,将参数通过url传到服务端。

下面举例说明 REST 风格的 URL 与传统 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
  • 我们发现 REST 风格的 URL 中最明显的就是参数不再使用“?”传递。这种风格的 URL 可读性更好,使得项目架构清晰,最关键的是 Spring MVC 也提供对这种风格的支持。
  • 但是也有弊端,对于国内项目,URL 参数有时会传递中文,而中文乱码是一个令人头疼的问题,所以我们应该根据实际情况进行灵活处理。很多网站都是传统 URL 风格与 REST 风格混搭使用。

6.1.2 http的方法规范

	Spring REST 风格可以简单理解为:使用 URL 表示资源时,每个资源都用一个独一无二的 URL 来表示,并使用 HTTP 方法表示操作,即准确描述服务器对资源的处理动作(GET、POST、PUT、DELETE),实现资源的增删改查。
	
	GET:表示获取资源。
    POST:表示新建资源。
    PUT:表示更新资源。
    DELETE:表示删除资源。
功能 url路径 请求方式
全查 /emp/find GET
单查 /emp/find/7369 GET
新增 /emp/add POST
修改 /emp/edit PUT
删除 /emp/remove/7369 DELETE

6.2 maven依赖

<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

  • 前端控制器的配置需要修改为支持restful风格。
  • 配置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 SpringMVC配置

在SpringMVC的配置中,需要添加对静态资源访问的处理,否则静态资源将无法正常使用。

<?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/>标签

配置默认Servlet处理器,使DispatcherServlet不拦截静态资源,将静态资源的处理经由Spring MVC框架交回Web应用服务器处理。

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

6.4.2 <mvc:resources/>标签

  • 对静态资源进行映射,由Spring MVC框架自己处理静态资源,并添加一些有用的附加值功能。
  • <mvc:resources/>允许静态资源放在任何地方,如WEB-INF目录下、类路径下等。
  • 通过location属性指定静态资源的位置,可以使用诸如"classpath:"等的资源前缀指定资源位置。
  • 传统Web容器的静态资源只能放在Web容器的根路径下,<mvc:resources />完全打破了这个限制。
<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 REST在同步请求中的使用

6.5.1 实体类

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

接口:

public interface UserDao {
    
    

    void insert(User user);

    void update(User user);

    void delete(Integer id);

    User selectById(Integer id);

    List<User> select();
}

实现类:

@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

接口:

public interface UserService {
    
    

    void add(User user);

    void edit(User user);

    void remove(Integer id);

    User findById(Integer id);

    List<User> find();
}

实现类:

@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 页面

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与DELETE请求

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

6.6.1 实体类

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

接口:

public interface EmpDao {
    
    
    
    void insert(Emp emp);

    void update(Emp emp);

    void delete(Integer empno);

    Emp selectById(Integer empno);

    List<Emp> select();
}

实现类:

@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

接口:

public interface EmpService {
    
    

    void add(Emp emp);

    void edit(Emp emp);

    void remove(Integer id);

    Emp findById(Integer id);

    List<Emp> find();
}

实现类:

@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 页面

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 解决Put请求参数传递的问题

	在异步请求中,可通过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>

猜你喜欢

转载自blog.csdn.net/ligonglanyuan/article/details/125318741
今日推荐