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;@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=" "></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=" "></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相关推荐
- Spring Boot 2 快速教程:WebFlux Restful CRUD 实践(三)
摘要: 原创出处 https://www.bysocket.com 「公众号:泥瓦匠BYSocket 」欢迎关注和转载,保留摘要,谢谢! 这是泥瓦匠的第102篇原创 03:WebFlux Web CR ...
- restful post请求_猿蜕变9——一文搞定SpringMVC的RESTFul套路
看过之前的蜕变系列文章,相信你对springMVC有了一定的认识.对springMVC的Interceptor拦截器,也有了一定的认识.今天我们来开启新讨论,讲一讲springMVC对那一种休闲风的支 ...
- SpringMVC响应Restful风格请求404
一.问题 在学习Springmvc时,使用Restful风格的url,页面提示404错误.为找到原因,编写一个简单的Restful测试用例如下: jsp页面: <a href="use ...
- springmvc教程--RESTful支持详解
RESTful支持 1.1 需求 RESTful方式商品修改.商品查询. 1.2 添加DispatcherServlet的rest配置 <servlet><servlet-name& ...
- Spring Boot 2 快速教程:WebFlux Restful CRUD 实践(三)
摘要:首先说明一下该博客教程是转载泥瓦匠BYSocket的文章 原创出处https://www.bysocket.com 「作者公众号:泥瓦匠BYSocket 」 原文地址:https://www.b ...
- SpringMVC中RestFul风格
先说一下什么是RestFul风格,以一个链接为例子,如果我们访问一个网页,想要给a和b传参数,传统的方式是?a=1&b=2,而RestFul就是改变了传统的方式,用/a/1/2的形式,达到了简 ...
- spring 3.0 应用springmvc 构造RESTful URL 详细讲解
在线springmvc_rest demo 由于下一版本的rapid-framwork需要集成spring RESTful URL,所以研究了一下怎么搭建. 并碰到了一下问题. springmvc 3 ...
- 007 使用SpringMVC开发restful API五--异常处理
一:任务 1.任务 Spring Boot中默认的错误机制处理机制 自定义异常处理 二:Spring Boot中的默认错误处理机制 1.目前 浏览器访问的时候, restful 接口主要是根据状态码进 ...
- (SpringMVC)RestFul和Controller
文章目录 1. 控制器Controller 1.1 实现Controller接口 1.2 使用注解@Controller 2. RestFul 风格 1. 控制器Controller 控制器复杂提供访 ...
最新文章
- 学习前端工程师手册--学习记录
- nginx thinkphp 配置pathinfo
- SSM格式化导出报表时间的格式
- ElasticSearch之动态映射和模板
- 基本类型理解巩固及补码原理总结
- 【华为云技术分享】数据管理服务DAS 之 数据库自动化运维功能展播4:慢SQL
- mysql5.7.28升级到5.7.29_MySQL升级5.7.29
- Activity的生命周期方面复习笔记
- Linux下常用的压缩解压命令[收藏]
- 伺服系统(自动控制系统)
- pc banner图 自适应 图片不变型
- 【江枫 】Oracle 9i和10g在create index和rebuild index的统计信息的区别
- 使用Python探索四大名著【红楼梦】人物之间的关系,简直帅呆了
- rviz显示矩形框BoundingBox
- 【树莓派C语言开发】实验02:RGB小灯
- 利用Python3四舍五入保留两位小数
- 【时间序列】TFT:Temporal Fusion Transformers
- android发送微信请求失败,安卓微信浏览器POST请求发不出去。
- 修改ubuntu中ens33的
- flowable流程引擎基础概念总结
热门文章
- Windows 7 and Windows Server 2008 R2 中文版已发布在 MSDN and TechNet Plus 订阅
- Halium 9 尝鲜 -- 在小米平板4上的移植 (七)
- 安卓镜像刻录软件_Android烧录工具-安卓烧录工具下载v6.0.43 官方最新版-西西软件下载...
- c语言 小学生数学考试软件下载,小学数学试题练习
- 基站网口损坏检查方法
- marquee功能:marquee的速度怎么设置
- 软件需求分析(以美团外卖为例)
- DOS命令:cd显示当前目录名或改变当前目录
- HP大中华区总裁孙振耀撰文谈退休并畅谈人生【全详细】
- 如何将计算机的名称改成英文翻译,电脑中的文档怎么进行中英文的翻译