1、配置 web.xml
<!-- 配置 SpringMVC DispatcherServlet --> <servlet> <servlet-name>dispatcher</servlet-name> <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class> <!-- 配置 DispatcherServlet 的一个初始化参数: 配置 SpringMVC 配置文件的位置和名称 --> <!-- 实际上也可以不通过 contextConfigLocation 来配置 SpringMVC 的配置文件, 而使用默认的. 默认的配置文件为: /WEB-INF/<servlet-name>-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>dispatcher</servlet-name> <url-pattern>/</url-pattern> </servlet-mapping> <!-- 配置 字符编码过滤器 --> <filter> <filter-name>SpringCharacterEncodingFilter</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>SpringCharacterEncodingFilter</filter-name> <url-pattern>/*</url-pattern> </filter-mapping> <!-- 配置支持RESTFul风格请求的 HiddenHttpMethodFilter 过滤器 ,把 POST 请求转为 DELETE、PUT 请求--> <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>
2、配置 Spring MVC 配置文件
<!-- 配置自动扫描的包 --> <context:component-scan base-package="com.cg"></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>
<!-- 放行访问静态资源文件的请求,此处为 js 文件放行 -->
<mvc:default-servlet-handler/>
<mvc:annotation-driven></mvc:annotation-driven>
3、显示所以员工的列表页面
<%@ 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> <script type="text/javascript" src="scripts/jquery-1.9.1.min.js"></script> <script type="text/javascript"> $(function(){//将 GET 请求转换为 POST 请求 $(".delete").click(function(){ var href = $(this).attr("href"); $("form").attr("action", href).submit(); return false; }); }) </script> </head> <body> <form action="" method="POST">
<!-- name 属性值是给 web.xml 中配置的 HiddenHttpMethodFilter 使用,
HiddenHttpMethodFilter 通过 value 的属性值将 POST 请求转换为对应的 DELETE 或 POST 请求--> <input type="hidden" name="_method" value="DELETE"/> </form> <c:if test="${empty requestScope.employees }"> 没有任何员工信息. </c:if> <c:if test="${!empty requestScope.employees }"> <table border="1" cellpadding="10" cellspacing="0"> <tr> <th>ID</th> <th>LastName</th> <th>Email</th> <th>Gender</th> <th>Department</th> <th>Edit</th> <th>Delete</th> </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>
4、添加和修改员工信息的页面
<%@page import="java.util.HashMap"%> <%@page import="java.util.Map"%> <%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%> <%@ taglib prefix="form" uri="http://www.springframework.org/tags/form" %> <%@ 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> <!-- 1. WHY 使用 form 标签呢 ? 可以更快速的开发出表单页面, 而且可以更方便的进行表单值的回显 2. 注意: 可以通过 modelAttribute 属性指定绑定的模型属性, 若没有指定该属性,则默认从 request 域对象中读取 command 的表单 bean 如果该属性值也不存在,则会发生错误。 --> <br><br> <form:form action="${pageContext.request.contextPath }/emp" method="POST" modelAttribute="employee"> <c:if test="${!empty employee.id}"> <form:hidden path="id"/> <input type="hidden" name="_method" value="PUT"/> </c:if> <c:if test="${empty employee.id}"> LastName: <form:input path="lastName"/> </c:if> <br> Email: <form:input path="email"/> <br>
<!-- 有更好的处理方式,此次方便演示,直接使用 java 脚本处理 --> <% Map<String, String> genders = new HashMap<String, String>(); genders.put("1", "Male"); genders.put("0", "Female"); request.setAttribute("genders", genders); %> Gender: <br> <form:radiobuttons path="gender" items="${genders }" delimiter="<br>"/> <br> Department: <form:select path="department.id" items="${departments }" itemLabel="departmentName" itemValue="id"></form:select> <br> <input type="submit" value="Submit"/> </form:form> </body>
5、核心的处理类
package com.cg.crud.handlers; import java.util.Map; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Controller; import org.springframework.validation.BindingResult; import org.springframework.validation.FieldError; import org.springframework.web.bind.annotation.ModelAttribute; import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMethod; import org.springframework.web.bind.annotation.RequestParam; import com.cg.crud.dao.DepartmentDao; import com.cg.crud.dao.EmployeeDao; import com.cg.crud.entities.Employee; @Controller public class EmployessHanlder { @Autowired private EmployeeDao employeeDao; @Autowired private DepartmentDao departmentDao; /** * 获取所有的员工 * @param map * @return */ @RequestMapping(value="/emps") public String list(Map<String, Object> map){ map.put("employees", employeeDao.getAll()); return "list"; } /** * 在修改员工信息后点击保存后,自动用此方法在接收页面传递参数前从数据库中获取更新前的对象信息, * 然后把表单中传递的新修改信息重新赋值到 Map key 指向的对象中,这样处理后更新操作的目标方法的入参就会 * 获取到既有新修改信息又有未修改信息的 Bean对象 * @param id * @param map */ @ModelAttribute public void getEmployee(@RequestParam(value="id", required=false) Integer id, Map<String,Object> map){ if(id != null){ map.put("employee", employeeDao.get(id)); } } /** * 响应用户的修改操作,修改时员工时,获取单个员工的详细信息并将视图跳转到修改页面 * @param id * @param map */ @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"; } /** * 响应更新员工信息时保存操作的目标方法 * @param employee * @return */ @RequestMapping(value="/emp", method=RequestMethod.PUT) public String update(Employee employee){ employeeDao.save(employee); return "redirect:/emps"; } /** * 响应请求添加员工操作的目标方法(跳转到添加页面) * @param map * @return */ @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"; } /** * 响应添加员工时保存操作的目标方法 * @param employee * @param result * @return */ @RequestMapping(value="/emp",method=RequestMethod.POST) public String save(Employee employee,BindingResult result){ if(result.getErrorCount() > 0){ for (FieldError error : result.getFieldErrors()) { System.out.println(error.getField() + " $$ " + error.getDefaultMessage()); } } employeeDao.save(employee); return "redirect:/emps"; } /** * 响应删除员工操作的目标方法 * @param id * @return */ @RequestMapping(value="/emp/{id}", method=RequestMethod.DELETE) public String delete(@PathVariable(value="id") Integer id){ employeeDao.delete(id); return "redirect:/emps"; } }