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;@Autowiredprivate 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() {}@Overridepublic 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;}@Overridepublic 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 {@Autowiredprivate EmployeeDao employeeDao;@Autowiredprivate 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:可以是一个 List、String[] 或 MapitemValue:指定 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中添加:
@ModelAttributepublic 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后:

  • 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. 处理静态资源

SpringMVC 13. RESTful CRUD相关推荐

  1. Spring Boot 2 快速教程:WebFlux Restful CRUD 实践(三)

    摘要: 原创出处 https://www.bysocket.com 「公众号:泥瓦匠BYSocket 」欢迎关注和转载,保留摘要,谢谢! 这是泥瓦匠的第102篇原创 03:WebFlux Web CR ...

  2. restful post请求_猿蜕变9——一文搞定SpringMVC的RESTFul套路

    看过之前的蜕变系列文章,相信你对springMVC有了一定的认识.对springMVC的Interceptor拦截器,也有了一定的认识.今天我们来开启新讨论,讲一讲springMVC对那一种休闲风的支 ...

  3. SpringMVC响应Restful风格请求404

    一.问题 在学习Springmvc时,使用Restful风格的url,页面提示404错误.为找到原因,编写一个简单的Restful测试用例如下: jsp页面: <a href="use ...

  4. springmvc教程--RESTful支持详解

    RESTful支持 1.1 需求 RESTful方式商品修改.商品查询. 1.2 添加DispatcherServlet的rest配置 <servlet><servlet-name& ...

  5. Spring Boot 2 快速教程:WebFlux Restful CRUD 实践(三)

    摘要:首先说明一下该博客教程是转载泥瓦匠BYSocket的文章 原创出处https://www.bysocket.com 「作者公众号:泥瓦匠BYSocket 」 原文地址:https://www.b ...

  6. SpringMVC中RestFul风格

    先说一下什么是RestFul风格,以一个链接为例子,如果我们访问一个网页,想要给a和b传参数,传统的方式是?a=1&b=2,而RestFul就是改变了传统的方式,用/a/1/2的形式,达到了简 ...

  7. spring 3.0 应用springmvc 构造RESTful URL 详细讲解

    在线springmvc_rest demo 由于下一版本的rapid-framwork需要集成spring RESTful URL,所以研究了一下怎么搭建. 并碰到了一下问题. springmvc 3 ...

  8. 007 使用SpringMVC开发restful API五--异常处理

    一:任务 1.任务 Spring Boot中默认的错误机制处理机制 自定义异常处理 二:Spring Boot中的默认错误处理机制 1.目前 浏览器访问的时候, restful 接口主要是根据状态码进 ...

  9. (SpringMVC)RestFul和Controller

    文章目录 1. 控制器Controller 1.1 实现Controller接口 1.2 使用注解@Controller 2. RestFul 风格 1. 控制器Controller 控制器复杂提供访 ...

最新文章

  1. 学习前端工程师手册--学习记录
  2. nginx thinkphp 配置pathinfo
  3. SSM格式化导出报表时间的格式
  4. ElasticSearch之动态映射和模板
  5. 基本类型理解巩固及补码原理总结
  6. 【华为云技术分享】数据管理服务DAS 之 数据库自动化运维功能展播4:慢SQL
  7. mysql5.7.28升级到5.7.29_MySQL升级5.7.29
  8. Activity的生命周期方面复习笔记
  9. Linux下常用的压缩解压命令[收藏]
  10. 伺服系统(自动控制系统)
  11. pc banner图 自适应 图片不变型
  12. 【江枫 】Oracle 9i和10g在create index和rebuild index的统计信息的区别
  13. 使用Python探索四大名著【红楼梦】人物之间的关系,简直帅呆了
  14. rviz显示矩形框BoundingBox
  15. 【树莓派C语言开发】实验02:RGB小灯
  16. 利用Python3四舍五入保留两位小数
  17. 【时间序列】TFT:Temporal Fusion Transformers
  18. android发送微信请求失败,安卓微信浏览器POST请求发不出去。
  19. 修改ubuntu中ens33的
  20. flowable流程引擎基础概念总结

热门文章

  1. Windows 7 and Windows Server 2008 R2 中文版已发布在 MSDN and TechNet Plus 订阅
  2. Halium 9 尝鲜 -- 在小米平板4上的移植 (七)
  3. 安卓镜像刻录软件_Android烧录工具-安卓烧录工具下载v6.0.43 官方最新版-西西软件下载...
  4. c语言 小学生数学考试软件下载,小学数学试题练习
  5. 基站网口损坏检查方法
  6. marquee功能:marquee的速度怎么设置
  7. 软件需求分析(以美团外卖为例)
  8. DOS命令:cd显示当前目录名或改变当前目录
  9. HP大中华区总裁孙振耀撰文谈退休并畅谈人生【全详细】
  10. 如何将计算机的名称改成英文翻译,电脑中的文档怎么进行中英文的翻译