使用Spring MVC编写一个Employee的CRUD项目,主要是编写Controller,员工数据保存在Map中,不使用数据库
Spring MVC 环境搭建
新建maven项目spring-mvc-crud,项目创建过程与配置方式及其maven依赖,创建过程参考QA 由浅入深 Spring Framework 5.0(十)- Spring MVC Restful,这里不在赘述。
在项目中新增entity包,保存Employee和Department实体类
代码语言:javascript复制public class Department {
private Integer id;
private String departmentName;
// 省略getter/setter/toString方法
}
代码语言:javascript复制public class Employee {
private Integer id;
private String lastName;
private String email;
//1 male, 0 female
private Integer gender;
private Department department;
//省略getter/setter/toString()方法
}
增加dao包,保存EmployeeDao和DepartmentDao
代码语言:javascript复制@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, "Stark", "stark@stark-industry.com", 1, new Department(101, "Stark Industries")));
employees.put(1002, new Employee(1002, "Steve", "steve@gmail.com", 1, new Department(102, "US Army")));
employees.put(1003, new Employee(1003, "Thor", "thor@gmail.com", 1, new Department(103, "Asgard")));
employees.put(1004, new Employee(1004, "Banner", "banner@gmail.com", 1, new Department(104, "None")));
employees.put(1005, new Employee(1005, "Natasha", "natash@gmail.com", 0, new Department(105, "S.H.I.E.L.D. ")));
employees.put(1006, new Employee(1006, "Clint", "client@gmail.com", 1, new Department(105, "S.H.I.E.L.D. ")));
}
//初始id
private static Integer initId = 1007;
public void save(Employee employee){
if(employee.getId() == null){
employee.setId(initId );
}
//根据部门id单独查出部门信息设置到员工对象中,页面提交的只需要提交部门的id
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);
}
}
代码语言:javascript复制@Repository
public class DepartmentDao {
private static Map<Integer, Department> departments = null;
static{
departments = new HashMap<Integer, Department>();
departments.put(101, new Department(101, "Stark Industries"));
departments.put(102, new Department(102, "US Army"));
departments.put(103, new Department(103, "Asgard"));
departments.put(104, new Department(104, "None"));
departments.put(105, new Department(105, "S.H.I.E.L.D. "));
}
public Collection<Department> getDepartments(){
return departments.values();
}
public Department getDepartment(Integer id){
return departments.get(id);
}
}
Employee列表展示
获取员工列表的步骤:
- 项目启动,直接访问index.jsp页面
- 直接发送/emps请求
- Controller查询所有员工
- 放入请求域中
- 转发到list页面展示
controller包中增加EmployeeController,控制员工的增删改查。首先增加一个list方法,获取员工列表,将员工信息保存在emps变量中,方便页面进行提取
代码语言:javascript复制@Controller
public class EmployeeController {
@Resource
private EmployeeDao employeeDao;
@RequestMapping("/emps")
public String list(Model model){
Collection<Employee> employees = employeeDao.getAll();
model.addAttribute("emps",employees);
return "list";
}
}
在page目录下增加list.jsp,用来展示员工列表,body标签中增加一个表头,并定义列属性
代码语言:javascript复制<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>List</title>
</head>
<body>
<h1>员工列表</h1>
<table>
<tr>
<th>ID</th>
<th>LastName</th>
<th>Email</th>
<th>Gender</th>
<th>Dep</th>
<th>EDIT</th>
<th>DELETE</th>
</tr>
</table>
</body>
</html>
修改index.jsp页面,使项目启动后自动跳转到员工列表页面
代码语言:javascript复制<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%--访问项目首先展示员工列表页--%>
<jsp:forward page="/emps"></jsp:forward>
pxm.xml导入jsp api依赖,修改list.jsp页面
代码语言:javascript复制<!-- https://mvnrepository.com/artifact/javax.servlet.jsp.jstl/jstl -->
<dependency>
<groupId>javax.servlet.jsp.jstl</groupId>
<artifactId>jstl</artifactId>
<version>1.2</version>
</dependency>
页面顶部导入
代码语言:javascript复制<%@taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>
修改table内容,使用forEach循环获取保存在emps中的员工信息
代码语言:javascript复制<table border="1" cellpadding="5" cellspacing="0"
>
<tr>
<th>ID</th>
<th>LastName</th>
<th>Email</th>
<th>Gender</th>
<th>Dep</th>
<th>EDIT</th>
<th>DELETE</th>
</tr>
<c:forEach items="${emps}" var="emp">
<tr>
<td>${emp.id }</td>
<td>${emp.lastName}</td>
<td>${emp.email }</td>
<td>${emp.gender==0?"女":"男" }</td>
<td>${emp.department.departmentName }</td>
<th>EDIT</th>
<th>DELETE</th>
</tr>
</c:forEach>
</table>
重新启动Tomcat,浏览器输入http://localhost:8080/
新增Employee
新增Eemployee步骤:
- 在列表页面点击添加超链接
- 查询出所有部门信息,跳转至添加页面
- 输入新增员工信息,点击保存
- Controller接收到新增员工信息,执行保存操作
- 再次跳转至list页面
EmployeeController中新增addPage方法,跳转到add页面
代码语言:javascript复制// 点击增加按钮跳转至增加页面,并查询所有部分信息,供新增员工时选择
@RequestMapping("/add")
public String addPage(Model model){
Collection<Department> departments = depmentDao.getDepartments();
model.addAttribute("depts",departments);
return "add";
}
新增add页面,form表单中的属性应该与Employee实体类保持一致,部门信息通过for循环展示所有可选择的部门
代码语言:javascript复制<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%@taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Insert title here</title>
</head>
<body>
<h1>员工添加</h1>
<form action="">
lastName:<input type="text" name="lastName"/><br/>
email:<input type="text" name="email"/><br/>
gender: <br/>
男:<input type="radio" name="gender" value="1"/><br/>
女:<input type="radio" name="gender" value="0"><br/>
dept:
<select name="department.id">
<c:forEach items="${depts}" var="deptItem">
<!-- 标签体中的是在页面的提示选项信息,value才是真正提交的值 -->
<option value="${deptItem.id}">${deptItem.departmentName }</option>
</c:forEach>
</select>
<input type="submit" value="提交"/>
</form>
</body>
</html>
重新启动Tomcat,输入http://localhost:8080/ 点击列表地步的添加员工超链接,跳转至添加页面
添加员工操作
Spring MVC表单标签:通过 SpringMVC的表单标签可以实现将模型数据中的属性和 HTML 表单元素相绑定,以实现表单数据更便捷编辑和表单值的回显
首先在add页面上导入表单标签
代码语言:javascript复制<%@taglib prefix="form" uri="http://www.springframework.org/tags/form" %>
修改form表单,使用form标签
代码语言:javascript复制<form:form action="" modelAttribute="employee" method="POST">
<!-- path就是原来html-input的name项:需要写
path:
1)、当做原生的name项
2)、自动回显隐含模型中某个对象对应的这个属性的值
-->
LastName:<form:input path="lastName"/><br/>
Email:<form:input path="email"/><br/>
Gender:<br/>
男:<form:radiobutton path="gender" value="1"/><br/>
女:<form:radiobutton path="gender" value="0"/><br/>
Dept:
<!--
items="":指定要遍历的集合 ;自动遍历;遍历出的每一个元素是一个department对象
itemLabel="属性名":指定遍历出的这个对象的哪个属性是作为option标签体的值
itemValue="属性名":指定刚才遍历出来的这个对象的哪个属性是作为要提交 的value值
-->
<form:select path="department.id"
items="${depts}"
itemLabel="departmentName"
itemValue="id"></form:select><br/>
<input type="submit" value="保存"/>
</form:form>
重启Tomcat,点击列表页面的添加员工超链接,出现报错信息
这个报错是因为请求域中没有command,修改跳转到增加页面的方法
代码语言:javascript复制model.addAttribute("command", new Employee(null,"Peter","peter@gmail.com",1,depmentDao.getDepartment(101)));
这个员工的信息会在跳转到增加页面后直接显示出来
在页面上form标签中使用modelAttribute属性,指定取哪个字段的属性(替换command变量)
代码语言:javascript复制<form:form action="" modelAttribute="employee">
代码语言:javascript复制model.addAttribute("employee", new Employee());
增加员工添加的方法
代码语言:javascript复制@RequestMapping(value = "/emp", method = RequestMethod.POST)
public String addEmp(Employee employee){
System.out.println("要添加的员工信息:" employee);
employeeDao.save(employee);
// 返回列表页面
return "redirect:/emps";
}
重启Tomcat,点击进入新增页面,输入员工信息,点击保存,新增成功
修改Employee
修改Employee步骤:
- 任选一个员工点击EDIT超链接
- 查询这个员工的信息,跳转到编辑页面,页面展示选择的员工信息
- 编辑员工信息,点击提交
- Controller中方法保存修改的员工
- 再次返回list页面
首先要回显员工信息,改造list页面中table标签中的EDIT超链接
代码语言:javascript复制<td><a href="${ctp}/emp/${emp.id }">EDIT</a></td>
EmployeeController中增加方法,根据ID查询员工信息,并返回到员工信息编辑页面
代码语言:javascript复制@RequestMapping(value = "/emp/{id}", method = RequestMethod.GET)
public String getEmp(@PathVariable("id") Integer id, Model model) {
// 1、查出员工信息
Employee employee = employeeDao.get(id);
// 2、放在请求域中
model.addAttribute("employee", employee);
// 3、继续查出部门信息放在隐含模型中
Collection<Department> departments = departmentDao.getDepartments();
model.addAttribute("depts", departments);
return "edit";
}
增加员工信息编辑页面edit.jsp,该页面显示的员工信息就是要编辑的员工信息
代码语言:javascript复制<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%@taglib prefix="form" uri="http://www.springframework.org/tags/form" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Insert title here</title>
<%
pageContext.setAttribute("ctp", request.getContextPath());
%>
</head>
<body>
<h1>员工修改页面</h1>
<!-- modelAttribute:这个表单的所有内容显示绑定的是请求域中 employee的值-->
<form:form action="${ctp}/emp/${employee.id }"
modelAttribute="employee" method="post">
<input type="hidden" name="_method" value="put"/>
<input type="hidden" name="id" value="${employee.id }"/>
email:<form:input path="email"/><br/>
gender:&nbsp;&nbsp;&nbsp;
男:<form:radiobutton path="gender" value="1"/>&nbsp;&nbsp;&nbsp;
女:<form:radiobutton path="gender" value="0"/><br/>
dept:
<form:select path="department.id" items="${depts}"
itemLabel="departmentName" itemValue="id"></form:select>
<br/>
<input type="submit" value="修改"/>
</form:form>
</body>
</html>
重启Tomcat, 任意选择一个员工,点击EDIT,可以成功跳转到编辑页面
新增员工修改方法
代码语言:javascript复制@RequestMapping(value = "/emp/{id}", method = RequestMethod.PUT)
public String updateEmp(@ModelAttribute("employee")Employee employee/* ,@PathVariable("id")Integer id */) {
System.out.println("要修改的员工:" employee);
// xxxx 更新保存二合一;
employeeDao.save(employee);
return "redirect:/emps";
}
代码语言:javascript复制@ModelAttribute
public void myModelAttribute(
@RequestParam(value = "id", required = false) Integer id, Model model) {
if (id != null) {
Employee employee = employeeDao.get(id);
model.addAttribute("employee", employee);
}
System.out.println("hahha ");
}
重新启动Tomcat,修改Clint部门为None
删除Employee
删除Employee步骤:
- list页面点击删除超链接
- Controller处理删除请求,从Map中删除员工信息
- 再次返回list页面
Controller中增加删除方法
代码语言:javascript复制@RequestMapping(value="/emp/{id}",method=RequestMethod.DELETE)
public String deleteEmp(@PathVariable("id")Integer id){
employeeDao.delete(id);
return "redirect:/emps";
}
修改list页面的删除超链接
代码语言:javascript复制<td><a href="${ctp }/emp/${emp.id }" class="delBtn">delete</a></td>
在web目录下增加js文件夹,包含了jquery文件,dispatcherServlet-servlet.xml中配置静态资源请求
代码语言:javascript复制 <!-- 默认前端控制器是拦截所有资源(除过jsp),js文件就404了;要js文件的请求是交给tomcat处理的 -->
<!-- 告诉SpringMVC,自己映射的请求就自己处理,不能处理的请求直接交给tomcat -->
<!-- 静态资源能访问,动态映射的请求就不行 -->
<mvc:default-servlet-handler/>
<!-- springmvc可以保证动态请求和静态请求都能访问 -->
<mvc:annotation-driven></mvc:annotation-driven>
在添加员工超链接下增加代码
代码语言:javascript复制<form id="deleteForm" action="${ctp }/emp/${emp.id }" method="post">
<input type="hidden" name="_method" value="DELETE" />
</form>
<script type="text/javascript">
$(function(){
$(".delBtn").click(function(){
//0、确认删除?
//1、改变表单的action指向
$("#deleteForm").attr("action",this.href);
//2、提交表单
$("#deleteForm").submit();
return false;
});
});
</script>
重启Tomcat,执行删除操作