使用Spring MVC编写一个Employee的CRUD项目,主要是编写Controller,员工数据保存在Map中,不使用数据库
Spring MVC 环境搭建
新建maven项目spring-mvc-crud,项目创建过程与配置方式及其maven依赖,创建过程参考QA 由浅入深 Spring Framework 5.0(十)- Spring MVC Restful,这里不在赘述。
在项目中新增entity包,保存Employee和Department实体类
public class Department { private Integer id; private String departmentName; // 省略getter/setter/toString方法 } 复制代码
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
@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); } } 复制代码
@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变量中,方便页面进行提取
@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标签中增加一个表头,并定义列属性
<%@ 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页面,使项目启动后自动跳转到员工列表页面
<%@ page contentType="text/html;charset=UTF-8" language="java" %> <%--访问项目首先展示员工列表页--%> <jsp:forward page="/emps"></jsp:forward> 复制代码
pxm.xml导入jsp api依赖,修改list.jsp页面
<!-- https://mvnrepository.com/artifact/javax.servlet.jsp.jstl/jstl --> <dependency> <groupId>javax.servlet.jsp.jstl</groupId> <artifactId>jstl</artifactId> <version>1.2</version> </dependency> 复制代码
页面顶部导入
<%@taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%> 复制代码
修改table内容,使用forEach循环获取保存在emps中的员工信息
<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页面
// 点击增加按钮跳转至增加页面,并查询所有部分信息,供新增员工时选择 @RequestMapping("/add") public String addPage(Model model){ Collection<Department> departments = depmentDao.getDepartments(); model.addAttribute("depts",departments); return "add"; } 复制代码
新增add页面,form表单中的属性应该与Employee实体类保持一致,部门信息通过for循环展示所有可选择的部门
<%@ 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页面上导入表单标签
<%@taglib prefix="form" uri="http://www.springframework.org/tags/form" %> 复制代码
修改form表单,使用form标签
<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,修改跳转到增加页面的方法
model.addAttribute("command", new Employee(null,"Peter","peter@gmail.com",1,depmentDao.getDepartment(101))); 复制代码
这个员工的信息会在跳转到增加页面后直接显示出来
在页面上form标签中使用modelAttribute属性,指定取哪个字段的属性(替换command变量)
<form:form action="" modelAttribute="employee"> 复制代码
model.addAttribute("employee", new Employee()); 复制代码
增加员工添加的方法
@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超链接
<td><a href="${ctp}/emp/${emp.id }">EDIT</a></td> 复制代码
EmployeeController中增加方法,根据ID查询员工信息,并返回到员工信息编辑页面
@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,该页面显示的员工信息就是要编辑的员工信息
<%@ 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: 男:<form:radiobutton path="gender" value="1"/> 女:<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,可以成功跳转到编辑页面
新增员工修改方法
@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"; } 复制代码
@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中增加删除方法
@RequestMapping(value="/emp/{id}",method=RequestMethod.DELETE) public String deleteEmp(@PathVariable("id")Integer id){ employeeDao.delete(id); return "redirect:/emps"; } 复制代码
修改list页面的删除超链接
<td><a href="${ctp }/emp/${emp.id }" class="delBtn">delete</a></td> 复制代码
在web目录下增加js文件夹,包含了jquery文件,dispatcherServlet-servlet.xml中配置静态资源请求
<!-- 默认前端控制器是拦截所有资源(除过jsp),js文件就404了;要js文件的请求是交给tomcat处理的 --> <!-- 告诉SpringMVC,自己映射的请求就自己处理,不能处理的请求直接交给tomcat --> <!-- 静态资源能访问,动态映射的请求就不行 --> <mvc:default-servlet-handler/> <!-- springmvc可以保证动态请求和静态请求都能访问 --> <mvc:annotation-driven></mvc:annotation-driven> 复制代码
在添加员工超链接下增加代码
<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,执行删除操作