步骤:
-创建web project
– 加入 jar 包
– 在 web.xml 中配置 DispatcherServlet 并且配置HiddenHttpMethodFilter:把POST请求转为DELETE、PUT请求
<?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"> <!--配置DispatcherServlet--> <servlet> <servlet-name>springDispatcherServlet</servlet-name> <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class> <init-param> <param-name>contextConfigLocation</param-name> <param-value>classpath:springmvc.xml</param-value> </init-param> </servlet> <servlet-mapping> <servlet-name>springDispatcherServlet</servlet-name> <url-pattern>/</url-pattern> </servlet-mapping> <!--配置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> </web-app>
– 加入 Spring MVC 的配置文件 即上面配置的 springmvc.xml
1.配置自动扫描的包
2.配置视图解析器
<?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" 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"> <!--配置自动扫描的包--> <context:component-scan base-package="crud"></context:component-scan> <!--配置视图解析器--> <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver"> <property name="prefix" value="/WEB-INF/views/"></property> <property name="suffix" value=".jsp"></property> </bean> </beans>
Employee和Department实体类 EmployeeDao和DepartmentDao如下:
JavaEE——SpringMVC--Example--Employee和Department实体类 & EmployeeDao和DepartmentDao
EmployeeHandler如下:
在jsp页面上写显式的标签
首先导入
添加员工信息的页面 input.jsp
使用Spring的表单标签 Spring 的表单标签 form 标签
1. WHY 使用 form 标签呢 ?
可以更快速的开发出表单页面, 而且可以更方便的进行表单值的回显
2. 注意:
可以通过 modelAttribute 属性指定绑定的模型属性,
若没有指定该属性,则默认从 request 域对象中读取 command 的表单 bean
如果该属性值也不存在,则会发生错误。
1. 显示所有员工信息
– URI:emps
– 请求方式:GET
– 显示效果
list.jsp
<%-- Created by IntelliJ IDEA. User: Skye Date: 2018/1/25 Time: 10:12 To change this template use File | Settings | File Templates. --%> <%@ page contentType="text/html;charset=UTF-8" language="java" %> <%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %> <html> <head> <title>Title</title> <script type="text/javascript" src="scripts/jquery-2.0.0.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 action="" method="post"> <%--给HiddenHttpMethodFilter用的--%> <input type="hidden" name="_method" value="DELETE"/> </form> <c:if test="${empty requestScope.employees}"> 没有员工信息 </c:if> <c:if test="${!empty requestScope.employees}"> <table cellpadding="10" cellspacing="0" border="1"> <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> <a href="emp">Add Employee</a> </c:if> </body> </html>
请求的handler
@RequestMapping("/emps") public String list(Map<String, Object> map){ map.put("employees", employeeDao.getAll()); return "list"; }
2. 添加所有员工信息
– 显示添加页面:
• URI:emp
• 请求方式:GET
• 显示效果
获取员工信息(空的)
@RequestMapping(value="/emp", method= RequestMethod.GET) public String input(Map<String, Object> map){ map.put("department", departmentDao.getDepartments()); map.put("employee", new Employee()); return "input"; }
显示到input.jsp
<%@ page import="java.util.Map" %> <%@ page import="java.util.HashMap" %><%-- Created by IntelliJ IDEA. User: Skye Date: 2018/1/26 Time: 9:41 To change this template use File | Settings | File Templates. --%> <%@ 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>Title</title> </head> <body> <%--1. WHY 使用 form 标签呢 ? 可以更快速的开发出表单页面, 而且可以更方便的进行表单值的回显 2. 注意: 可以通过 modelAttribute 属性指定绑定的模型属性, 若没有指定该属性,则默认从 request 域对象中读取 command 的表单 bean 如果该属性值也不存在,则会发生错误。--%> <form:form action="${pageContext.request.contextPath}/emp" method="post" modelAttribute="employee"> <c:if test="${employee.id == null}"> LastName: <form:input path="lastName"/> <br> </c:if> <c:if test="${employee.id != null}"> <form:hidden path="id"/> <input type="hidden" name="_method" value="PUT"/> <%-- 对于 _method 不能使用 form:hidden 标签, 因为 modelAttribute 对应的 bean (employee)中没有 _method 这个属性 --%> </c:if> Email <form:input path="email"/> <br> <% Map<String, String> genders = new HashMap(); genders.put("1", "Male"); genders.put("0", "Female"); request.setAttribute("genders", genders); %> Gender <form:radiobuttons path="gender" items="${genders}"/> <br> Department <form:select path="department.id" items="${department}" itemLabel="departmentName" itemValue="id"></form:select> <br> <input type="submit" value="Submit"/> </form:form> </body> </html>
– 添加员工信息:
• URI:emp
• 请求方式:POST
• 显示效果:完成添加,重定向到 list 页面。
@RequestMapping(value="/emp", method = RequestMethod.POST) public String save(Employee employee) { employeeDao.save( employee ); return "redirect:/emps"; }
3. 删除操作
– URL:emp/{id}
– 请求方式:DELETE
– 删除后效果:对应记录从数据表中删除
@RequestMapping(value="/emp/{id}", method=RequestMethod.DELETE) public String delete(@PathVariable("id")Integer id){ employeeDao.delete(id); return "redirect:/emps"; }
难点:要把GET请求转为DELETE请求
一般的超链接就是GET请求,所以需要借助于JS
<script type="text/javascript" src="scripts/jquery-2.0.0.min.js"></script>
但是只这样会出错,会被SpringMVC拦截
SpringMVC 处理静态资源:
1. 为什么会有这样的问题:
优雅的 REST 风格的资源URL 不希望带 .html 或 .do 等后缀
若将 DispatcherServlet 请求映射配置为 /,
则 Spring MVC 将捕获 WEB 容器的所有请求, 包括静态资源的请求, SpringMVC 会将他们当成一个普通请求处理,
因找不到对应处理器将导致错误。
2. 解决: 在 SpringMVC 的配置文件中配置 <mvc:default-servlet-handler/>
default-servlet-handler 将在 SpringMVC 上下文中定义一个 DefaultServletHttpRequestHandler,
它会对进入 DispatcherServlet 的请求进行筛查, 如果发现是没有经过映射的请求, 就将该请求交由 WEB 应用服务器默认的
Servlet 处理. 如果不是静态资源的请求,才由 DispatcherServlet 继续处理
一般 WEB 应用服务器默认的 Servlet 的名称都是 default.
若所使用的 WEB 服务器的默认 Servlet 名称不是 default,则需要通过 default-servlet-name 属性显式指定
<mvc:default-servlet-handler/> <mvc:annotation-driven></mvc:annotation-driven>
首先显示页面要有
<body> <c:if test="${empty requestScope.employees}"> 没有员工信息 </c:if> <c:if test="${!empty requestScope.employees}"> <table cellpadding="10" cellspacing="0" border="1"> <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="">Edit</a></td> <td><a class="delete" href="emp/${emp.id}">Delete</a></td> </tr> </c:forEach> </table> <a href="addEmp">Add Employee</a> </c:if> </body>
然后在该页面利用JS添加一个function,来将GET请求转换为POST请求,将POST请求提交
<script type="text/javascript" src="scripts/jquery-2.0.0.min.js"></script> <script type="text/javascript"> $(function(){ $(".delete").click(function(){ var href = $(this).attr("href"); $("form").attr("action", href).submit(); return false; }); }) </script>
进而将POST转换为DELETE请求
<form action="" method="post"> <%--给HiddenHttpMethodFilter用的--%> <input type="hidden" name="_method" value="DELETE"/> </form>
目标的handler
@RequestMapping(value="/emp/{id}", method=RequestMethod.DELETE) public String delete(@PathVariable("id")Integer id){ employeeDao.delete(id); return "redirect:/emps"; }
• 4. 修改操作:lastName 不可修改!
– 显示修改页面:
• URI:emp/{id}
• 请求方式:GET
• 显示效果:回显表单。
– 修改员工信息:
• URI:emp
• 请求方式:PUT
• 显示效果:完成修改,重定向到 list 页面。
对于修改操作由于不能修改lastName 所以回显表单时不显式表单,
<c:if test="${employee.id == null}"> LastName: <form:input path="lastName"/> <br> </c:if> <c:if test="${employee.id != null}"> <form:hidden path="id"/> <input type="hidden" name="_method" value="PUT"/> <%-- 对于 _method 不能使用 form:hidden 标签, 因为 modelAttribute 对应的 bean (employee)中没有 _method 这个属性 --%> </c:if>
请求的响应
@RequestMapping(value="/emp", method = RequestMethod.PUT) public String update(Employee employee){ employeeDao.save(employee); return "redirect:/emps"; }
然后再转到显示页面这样会丢失lastName
解决办法:JavaEE——SpringMVC(2)--处理模型数据 中的@ModelAttribute
@ModelAttribute public void getEmployee(@RequestParam(value="id", required=false)Integer id, Map<String, Object> map){ if(id != null){ map.put("employee", employeeDao.get(id)); } } @RequestMapping(value="/emp", method = RequestMethod.PUT) public String update(Employee employee){ employeeDao.save(employee); return "redirect:/emps"; }