SpringMVC 13. RESTful CRUD

RESTful CRUD

1 前置准备

1.0 配置文件

  • pom.xml
<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/maven-v4_0_0.xsd">
  <modelVersion>4.0.0</modelVersion>
  <groupId>com.ifox.hgx</groupId>
  <artifactId>springMVC_1</artifactId>
  <packaging>war</packaging>
  <version>1.0-SNAPSHOT</version>
  <name>springMVC_1 Maven Webapp</name>
  <url>http://maven.apache.org</url>

  <dependencies>

    <!-- https://mvnrepository.com/artifact/org.springframework/spring-webmvc -->
    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-webmvc</artifactId>
      <version>5.0.3.RELEASE</version>
    </dependency>

    <!-- https://mvnrepository.com/artifact/javax.servlet/javax.servlet-api -->
    <dependency>
      <groupId>javax.servlet</groupId>
      <artifactId>javax.servlet-api</artifactId>
      <version>3.1.0</version>
      <scope>provided</scope>
    </dependency>

  </dependencies>
  <build>
    <finalName>springMVC_1</finalName>
  </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_3_1.xsd"
         version="3.1">




    <!--编码过滤器-->
    <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>

    <!--配置org.springframework.web.filter.HiddenHttpMethodFilter:可以把POST请求转为DELETE 或 POST 请求-->
    <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>

    <servlet>
        <servlet-name>springDispatcherServlet</servlet-name>
        <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
        <!--配置DispatcherServlet初始化参数:springMVC配置文件的位置和参数-->
        <!--也可以不通过contextConfigLocation来配置springMVC的配置文件,
        而使用默认的配置文件: /WEB-INF/views/<servlet-name>-servlet.xml
        即:springDispatcherServlet-servlet.xml
        -->
        <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>springDispatcherServlet</servlet-name>
        <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 http://www.springframework.org/schema/context/spring-context.xsd http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc.xsd">

    <!--配置自动扫描的包-->
    <context:component-scan base-package="com.ifox"></context:component-scan>

    <!--配置视图解析器:如何把handler 方法返回值解析为实际的物理视图-->
    <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
        <property name="prefix" value="/WEB-INF/views/"></property>
        <property name="suffix" value=".jsp"></property>
    </bean>

    <mvc:annotation-driven></mvc:annotation-driven>

</beans>

1.1 DAO

  • DepartmentDao.java
import com.ifox.restful_CRUD.entities.Department;
import org.springframework.stereotype.Repository;

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

@Repository
public class DepartmentDao {

    private static Map<Integer, Department> departments = null;

    static {
        departments = new HashMap<Integer, Department>();

        departments.put(101, new Department(101, "D-AA"));
        departments.put(102, new Department(102, "D-BB"));
        departments.put(103, new Department(103, "D-CC"));
        departments.put(104, new Department(104, "D-DD"));
        departments.put(105, new Department(105, "D-EE"));
    }

    public Collection<Department> getDepartments() {
        return departments.values();
    }

    public Department getDepartment(Integer id) {
        return departments.get(id);
    }

}
  • EmployeeDao.java
import java.util.Collection;
import java.util.HashMap;
import java.util.Map;

import com.ifox.restful_CRUD.entities.Department;
import com.ifox.restful_CRUD.entities.Employee;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Repository;


@Repository
public class EmployeeDao {

    private static Map<Integer, Employee> employees = null;

    @Autowired
    private DepartmentDao departmentDao;

    //为了简化,省略了数据库,使用静态代码块代替
    static{
        employees = new HashMap<Integer, Employee>();

        employees.put(1001, new Employee(1001, "E-AA", "aa@163.com", 1, new Department(101, "D-AA")));
        employees.put(1002, new Employee(1002, "E-BB", "bb@163.com", 1, new Department(102, "D-BB")));
        employees.put(1003, new Employee(1003, "E-CC", "cc@163.com", 0, new Department(103, "D-CC")));
        employees.put(1004, new Employee(1004, "E-DD", "dd@163.com", 0, new Department(104, "D-DD")));
        employees.put(1005, new Employee(1005, "E-EE", "ee@163.com", 1, new Department(105, "D-EE")));
    }

    private static Integer initId = 1006;

    public void save(Employee employee){
        if(employee.getId() == null){
            employee.setId(initId++);
        }

        employee.setDepartment(departmentDao.getDepartment(employee.getDepartment().getId()));
        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);
    }
}

1.2 entities

  • Department.java
public class Department {
    private Integer id ;
    private String departmentName ;

    public Integer getId() {
        return id;
    }

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

    public String getDepartmentName() {
        return departmentName;
    }

    public void setDepartmentName(String departmentName) {
        this.departmentName = departmentName;
    }

    public Department(Integer id, String departmentName) {
        this.id = id;
        this.departmentName = departmentName;
    }

    public Department() {
    }

    @Override
    public String toString() {
        return "Department{" +
                "id=" + id +
                ", departmentName='" + departmentName + '\'' +
                '}';
    }
}
  • Employee.java

public class Employee {
    private Integer id ;
    private String lastName ;
    private String email ;
    private Integer gender ;
    private Department department ;
    private Date birth ;

    public Date getBirth() {
        return birth;
    }

    public void setBirth(Date birth) {
        this.birth = birth;
    }

    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 Department getDepartment() {
        return department;
    }

    public void setDepartment(Department department) {
        this.department = department;
    }

    public Employee() {
    }

    public Employee(Integer id, String lastName, String email, Integer gender, Department department) {
        this.id = id;
        this.lastName = lastName;
        this.email = email;
        this.gender = gender;
        this.department = department;
    }

    public Employee(Integer id, String lastName, String email, Integer gender, Department department, Date birth) {
        this.id = id;
        this.lastName = lastName;
        this.email = email;
        this.gender = gender;
        this.department = department;
        this.birth = birth;
    }

     @Override
    public String toString() {
        return "Employee{" +
                "id=" + id +
                ", lastName='" + lastName + '\'' +
                ", email='" + email + '\'' +
                ", gender=" + gender +
                ", department=" + department +
                ", birth=" + birth +
                '}';
    }
}

2 显示所有员工信息(R)

  • URI:emps
  • 请求方式:GET
  • 显示效果

所有员工信息

1.1 handlers

@Controller
public class EmployeeHandler {
    @Autowired
    private EmployeeDao employeeDao;

    @Autowired
    private DepartmentDao departmentDao ;

    @RequestMapping("/emps")
    public String list(Map<String, Object> map) {
        map.put("employees", employeeDao.getAll());
        return "list";
    }
}

1.2 index.jsp

 <a href="/emps">list page</a>

1.3 list.jsp 显示页面

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<html>
<head>
    <title>restful crud list</title>
</head>
<body>

</form>

<c:if test="${employees == null || employees.size()==0}">
    <p style="color: red;">没有任何内容</p>
</c:if>

<c:if test="${employees != null && employees.size() != 0}">
    <table border="1" cellspacing="0" cellpadding="10">
        <tr>
            <td>ID</td>
            <td>LastName</td>
            <td>Email</td>
            <td>Gender</td>
            <td>Department</td>
            <td>Edit</td>
            <td>Delete</td>
        </tr>
        <c:forEach items="${requestScope.employees }" var="emp">
            <tr>
                <td>${emp.id }</td>
                <td>${emp.lastName }</td>
                <td>${emp.email }</td>
                <td>${emp.gender == 0 ? 'Female' : 'Male' }</td>
                <td>${emp.department.departmentName }</td>
                <td><a href="emp/${emp.id}">Edit</a></td>
                <td><a class="delete" href="emp/${emp.id}">Delete</a></td>
            </tr>
        </c:forEach>
    </table>
</c:if>
<br><br>

<a href="emp">Add New Employee</a>

</body>
</html>
  • pom.xml 加入:
<!-- https://mvnrepository.com/artifact/javax.servlet/jstl -->
    <dependency>
      <groupId>javax.servlet</groupId>
      <artifactId>jstl</artifactId>
      <version>1.2</version>
    </dependency>

此页面用到了SpringMVC的表单标签:

  • 通过 SpringMVC 的表单标签可以实现将模型数据中的属性和 HTML 表单元素相绑定,以实现表单数据更便捷编辑和表单值的回显

1.4 form 标签

  • 一般情况下,通过 GET 请求获取表单页面,而通过POST 请求提交表单页面,因此获取表单页面和提交表单页面的 URL 是相同的。只要满足该最佳条件的契约,<form:form> 标签就无需通过 action 属性指定表单提交的 URL
  • 可以通过 modelAttribute 属性指定绑定的模型属性,若没有指定该属性,则默认从 request 域对象中读取command 的表单 bean,如果该属性值也不存在,则会发生错误。

  • SpringMVC 提供了多个表单组件标签,如<form:input/><form:select/> 等,用以绑定表单字段的属性值,它们的共有属性如下:
    path:表单字段,对应 html 元素的 name 属性,支持级联属性
    htmlEscape:是否对表单值的 HTML 特殊字符进行转换,默认值为 true
    cssClass:表单组件对应的 CSS 样式类名
    cssErrorClass:表单组件的数据存在错误时,采取的 CSS 样式

form:input、form:password、form:hidden、form:textarea:对应 HTML 表单的 text、password、hidden、textarea标签

form:radiobutton:单选框组件标签,当表单 bean 对应的属性值和 value 值相等时,单选框被选中
form:radiobuttons:单选框组标签,用于构造多个单选框

     items:可以是一个 ListString[] 或 Map
     itemValue:指定 radio 的 value 值。可以是集合中 bean 的一个属性值
     itemLabel:指定 radio 的 label 值
     delimiter:多个单选框可以通过 delimiter 指定分隔符表单标签

form:checkbox:复选框组件。用于构造单个复选框
form:checkboxs:用于构造多个复选框。使用方式同form:radiobuttons 标签
form:select:用于构造下拉框组件。使用方式同form:radiobuttons 标签
form:option:下拉框选项组件标签。使用方式同form:radiobuttons 标签
form:errors:显示表单组件或数据校验所对应的错误 – <form:errors path= “ *” /> :显示表单所有的错误
<form:errors path= “ user*” /> :显示所有以 user 为前缀的属性对应的错误
<form:errors path= “ username” /> :显示特定表单对象属性的错误

3 添加新的员工(C)

3.1 Edit:显示添加员工页面

显示添加页面:

  • URI:emp
  • 请求方式:GET

示例:

  • jsp页面:
<a href="emp">Add New Employee</a>
  • handlers:EmployeeHandler.java中加入
@RequestMapping(value = "/emp", method = RequestMethod.GET)
    public String input(Map<String, Object> map) {
        map.put("departments",departmentDao.getDepartments() ) ;
        map.put("employee",new Employee()) ;
        return "input" ;
    }
  • input.jsp
<%@ page import="java.util.Map" %>
<%@ page import="java.util.HashMap" %>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%@ taglib prefix="form" uri="http://www.springframework.org/tags/form" %>

<html>
<head>
    <title>restful CRUD input</title>
</head>
<body>
<form:form action="${pageContext.request.contextPath}/emp" method="post" modelAttribute="employee">

    LastName: <form:input path="lastName"></form:input>
    <br>
    Email:<form:input path="email"></form:input>
    <br>
    <%
        Map<String,String> genders = new HashMap<>() ;
        genders.put("0","Male") ;
        genders.put("1","Female") ;
        request.setAttribute("genders",genders);
    %>
    Gender:<form:radiobuttons path="gender" items="${genders}" delimiter="&nbsp;&nbsp;"></form:radiobuttons>
    <br>
    Department:<form:select path="department.id" items="${departments}" itemLabel="departmentName" itemValue="id" ></form:select>
    <br>
    Birth:<form:input path="birth"></form:input>
    <br>
    <input type="submit" value="Submit">
</form:form>

</body>
</html>

点击后跳转到如下input.jsp页面

3.2 添加员工信息:

  • URI:emp
  • 请求方式:POST
  • 显示效果:完成添加,重定向到 list 页面。

添加员工

  • handlers:EmployeeHandler.java加入:
@RequestMapping(value = "/emp",method = RequestMethod.POST)
    public String save(Employee employee , Map<String,Object> map){
        System.out.println("save:"+employee);
        employeeDao.save(employee);
        return "redirect:/emps" ;
    }

点击提交,重定向到/emps 。

4 更新员工信息(U)

显示修改页面:

  • URI:emp/{id}
  • 请求方式:GET
  • 显示效果:回显表单。

  • handlers:EmployeeHandler.java中添加:


    @RequestMapping(value = "/emp/{id}",method = RequestMethod.GET)
    public String input(@PathVariable("id") Integer id ,Map<String,Object> map){
        map.put("employee",employeeDao.get(id)) ;
        map.put("departments",departmentDao.getDepartments()) ;
        return "input" ;
    }

list页面Edit:

<td><a href="emp/${emp.id}">Edit</a></td>

点击跳转到修改页面,为了简化,修改和添加员工用一个页面,跳转到input.jsp,但是也有不同的地方,修改操作不允许修改员工名字,和 id 。

修改员工信息:

  • URI:emp
  • 请求方式:PUT
  • 显示效果:完成修改,重定向到 list 页面。
    修改员工

  • 注意我们在web.xml中加入的:

 <!--配置org.springframework.web.filter.HiddenHttpMethodFilter:可以把POST请求转为DELETE 或 POST 请求-->
    <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>
  • handlers:EmployeeHandler.java中添加:
@ModelAttribute
    public void getEmployee(@RequestParam(value = "id",required = false) Integer id , Map<String,Object> map){
        if (id != null) {
            Employee e = employeeDao.get(id);
            map.put("employee",e) ;
        }
    }

    @RequestMapping(value = "/emp",method = RequestMethod.PUT )
    public String update(Employee employee){
       // employee.setLastName(employeeDao.get(employee.getId()).getLastName());
        employeeDao.save(employee);
        return "redirect:/emps" ;
    }
  • input.jsp页面:
<%@ page import="java.util.Map" %>
<%@ page import="java.util.HashMap" %>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%@ taglib prefix="form" uri="http://www.springframework.org/tags/form" %>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>

<html>
<head>
    <title>restful CRUD input</title>
</head>
<body>

<form:form action="${pageContext.request.contextPath}/emp" method="post" modelAttribute="employee">
    <c:if test="${employee.id == null}">
    LastName: <form:input path="lastName"></form:input>
        <form:errors path="lastName" cssStyle="color: red"></form:errors>
    </c:if>
    <br>

    <c:if test="${employee.id != null}">
        <form:hidden path="id"></form:hidden>
        <input type="hidden" name="_method" value="PUT">
    </c:if>
    Email:<form:input path="email"></form:input>
    <br>
    <%
        Map<String,String> genders = new HashMap<>() ;
        genders.put("0","Male") ;
        genders.put("1","Female") ;
        request.setAttribute("genders",genders);
    %>
    Gender:<form:radiobuttons path="gender" items="${genders}" delimiter="&nbsp;&nbsp;"></form:radiobuttons>
    <br>
    Department:<form:select path="department.id" items="${departments}" itemLabel="departmentName" itemValue="id" ></form:select>
    <br>
    Birth:<form:input path="birth"></form:input>
    <br>
    <input type="submit" value="Submit">
</form:form>

</body>
</html>
  • 在pom.xml中加入:
<!-- https://mvnrepository.com/artifact/javax.servlet/jstl -->
    <dependency>
      <groupId>javax.servlet</groupId>
      <artifactId>jstl</artifactId>
      <version>1.2</version>
    </dependency>

注意在其中我们写了一个@ModelAttribute注解修饰的方法,该方法会使得我们的employee是从数据库查到的,使得表单修改直接修改这个数据库查到的数据,从而避免了LastName在修改后为空的情况。

  • 修改完成,submit后,重定向到/emps 。

5 删除员工(D)

删除操作

  • URL:emp/{id}
  • 请求方式:DELETE
  • 删除后效果:对应记录从数据表中删除

  • 删除员工1001后:
    删除员工1001

  • list页面Delete:

 <td><a class="delete" href="emp/${emp.id}">Delete</a></td>

注意:我们需要DELETE请求,但是只能由POST请求转为DELETE,这里是GET请求,所以我们使用js来实现,选用Jquery来做。

  • list.jsp修改为:
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<html>
<head>
    <title>restful crud list</title>
    <%--处理静态资源--%>
    <%--添加--%>
    <script type="text/javascript" src="/scripts/jquery-1.9.1.min.js"></script>
    <script type="text/javascript">
        $(function(){
            $(".delete").click(function () {
                var href = $(this).attr("href") ;
                $("form").attr("action",href).submit() ;
                return false ;
            }) ;
        })
    </script>
</head>
<body>

<%--添加--%>
<form name="form" method="post" action="">
    <input type="hidden" name="_method" value="DELETE">
</form>

<c:if test="${employees == null || employees.size()==0}">
    <p style="color: red;">没有任何内容</p>
</c:if>

<c:if test="${employees != null && employees.size() != 0}">
    <table border="1" cellspacing="0" cellpadding="10">
        <tr>
            <td>ID</td>
            <td>LastName</td>
            <td>Email</td>
            <td>Gender</td>
            <td>Department</td>
            <td>Edit</td>
            <td>Delete</td>
        </tr>
        <c:forEach items="${requestScope.employees }" var="emp">
            <tr>
                <td>${emp.id }</td>
                <td>${emp.lastName }</td>
                <td>${emp.email }</td>
                <td>${emp.gender == 0 ? 'Female' : 'Male' }</td>
                <td>${emp.department.departmentName }</td>
                <td><a href="emp/${emp.id}">Edit</a></td>
                <%--添加--%>
                <td><a class="delete" href="emp/${emp.id}">Delete</a></td>
            </tr>
        </c:forEach>
    </table>
</c:if>
<br><br>

<a href="emp">Add New Employee</a>

</body>
</html>
  • handlers:Employee.java加入:
  @RequestMapping(value = "/emp/{id}",method = RequestMethod.DELETE)
    public String delete(@PathVariable("id") Integer id){
        employeeDao.delete(id);
        return "redirect:/emps" ;
    }

删除后直接跳重定向到/emps 。

注意: 此时你会发现DELETE不行,这是因为引入jquery是静态资源。我们将 DispatcherServlet 请求映射配置为le /, Spring MVC会将捕获WEB 容器的所有请求,包括静态资源的请求, SpringMVC 会将他们当成一个普通请求处理,因找不到对应处理器将导致错误。

所以我们需要在springmvc.xml配置文件中加入:

 <!--静态资源处理-->
    <mvc:default-servlet-handler></mvc:default-servlet-handler>

上一篇:SpringMVC 12. 重定向
下一篇:SpringMVC 14. 处理静态资源

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值