SpringMVC笔记--7综合案例RESTRUL_CRUD

第7章 综合案例RESTRUL_CRUD

7.1 RESTRUL_CRUD_需求

7.1.1 显示所有员工信息

1) URI:emps

2) 请求方式:GET

3) 显示效果

idLastNameEmailGenderDepartmentEditDelete
1001AAaa@163.comMaleAAEdieDelete

7

7.1.2 添加操作-去往添加页面

1) 显示添加页面:

2) URI:emp

3) 请求方式:GET

4) 显示效果

7.1.3 添加操作-添加员工

1) 添加员工信息:

2) URI:emp

3) 请求方式:POST

4) 显示效果:完成添加,重定向到 list 页面。

7.1.4 删除操作

1) URL:emp/{id}

2) 请求方式:DELETE

3) 删除后效果:对应记录从数据表中删除

7.1.5 修改操作-去往修改页面

1) URI:emp/{id}

2) 请求方式:GET

3) 显示效果:回显表单

7.1.6 修改操作-修改员工

1) URI:emp

2) 请求方式:PUT

3) 显示效果:完成修改,重定向到 list 页面。

7.1.7 相关的类

​ 省略了Service层,为了教学方便

1) 实体类:Employee、Department

2) Handler:EmployeeHandler

3) Dao:EmployeeDao、DepartmentDao

7.1.8 相关的页面

1) WebContent\WEB-INF\views\index.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<!-- 导入JSTL的标签库 -->
<%@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>
	<!-- 引入JQuery
		Springmvc处理静态资源的问题:
			静态资源:  .js  .css  .html  .txt  .png  .jpg  .avi 等. 
			
			因为DispatcherServlet的 <url-pattern> 配置的是/ , 会匹配到所有的请求(排除jsp的请求).
		         因为请求的.js文件,是一个静态资源请求,交给DispatcherServlet后就会出现no mapping found 问题。
		解决问题:
			1. 修改<url-pattern>为后缀匹配. 但是不建议这么做, 对REST的支持不好. 因为一个优秀的REST 不希望请求
			   URL带有任何后缀. 
			2. 在springmvc.xml中加上一个配置: <mvc:default-servlet-handler/> 
									      <mvc:annotation-driven/>  	
	
	 -->
	<script type="text/javascript" src="scripts/jquery-1.7.2.min.js"></script>
	<script type="text/javascript">
		$(function(){
			
			//给删除的<a>动态绑定事件
			$(".del").click(function(){
				//确认是否要删除
				var flag = window.confirm("是否要删除?");
				if(!flag){
					return false ;
				}
				
				//this :当前点击的dom对象
				//获取点击的超连接的href的值
				var href = $(this).attr("href");
				//将href的值设置到表单的action上,并提交
				$("form").attr("action",href).submit();
				
				//取消<a>的默认行为
				return false; 
			
			});
		});
	
	
	</script>
</head>
<body>
	<form action="" method="post">
		<input type="hidden" name="_method" value="DELETE">	
	</form>

	<h1 align="center">员工信息列表</h1>
	<table border="1px" align="center" width="70%" cellspacing="0px">
		<tr>
			<th>Id</th>
			<th>LastName</th>
			<th>Email</th>
			<th>Gender</th>
			<th>DeptName</th>
			<th>Operation</th>
		</tr>
		
		<!-- 通过迭代模型数据,生成表格 -->
		<c:forEach items="${emps }" var="emp">
			<tr align="center">
				<td>${emp.id }</td>
				<td>${emp.lastName }</td>
				<td>${emp.email }</td>
				<td>${emp.gender==0?"女":"男"}</td>
				<td>${emp.department.departmentName }</td>
				<td>
					<a href="emp/${emp.id}">Edit </a>
					&nbsp;&nbsp;
					<!-- 
						解决思路:
							给删除的超链接绑定事件, 当触发了点击事件,可以在事件处理函数中获取到要发送的请求URL,
							再将获取到的请求URL设置到某个表单的action属性上,再将表单提交。 
							最终将<a>的默认行为取消掉。
					
					 -->
					<a  class="del" href="emp/${emp.id}">Delete</a>
				</td>
			</tr>
		</c:forEach>
	</table>
	<!-- 
		去往添加页面,不能直接进行页面的简单跳转,因为添加页面中需要用到部门数据,因此需要
		到Handler中先查询到部门数据。再转发到添加页面.
	 -->
	<h2 align="center"><a href="emp">Add New Emp</a></h2>
	
</body>
</html>
2) WebContent\WEB-INF\views\input.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<!-- 导入Springmvc表单标签库 -->
<%@taglib prefix="form" uri="http://www.springframework.org/tags/form" %>

<!-- 导入JSTL标签库 -->
<%@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>
	<!-- Springmvc的表单标签:
			 1. 可以快速的开发表单
			 2. 可以更加方便的回显数据.
			 
		Springmvc表单标签遇到的问题:
			Neither BindingResult nor plain target object 
			for bean name 'command' available as request attribute
		
		问题原因: Springmvc的表单标签必须要进行数据的回显。 默认会使用"command"这个key到request中
		                  找回显的数据。如果找不到,则抛出异常。 
		问题解决: 让Springmvc可以通过"command"从request中找到要回显的数据. 
				还可以通过modelAttribute来指定一个key替换默认的command
				
		表单标签在最终执行时会转化成原始的HTML标签.	
	 -->
	 <form:form action="${pageContext.request.contextPath }/emp"  method="post" modelAttribute="employee">
	 	<!-- 
	 		判断是添加操作还是修改操作:
	 			根据回显的Employee对象的id值来判断: 如果有id就是修改  如果没有id就是添加操作
	 	 -->
	 	 <c:if test="${!empty employee.id }" var="flag">
	 	 		<!-- 修改操作 -->
	 	 		<form:hidden path="id"/>
	 	 		<!-- 隐藏PUT -->
	 	 		<input type="hidden" name="_method" value="PUT"/>
	 	 </c:if>
	 
	 
	 	lastName:<form:input path="lastName" /> <!-- path就相当于HTML中input标签中的name属性 -->
	 			<!--  <input type="text"	 name="lastName"/> -->
	 			<br/>
	 	Email: <form:input path="email"/>
	 	<br/>
	 		 <!-- radiobuttons 可以根据Map数据来生成单选框 -->
	 	Gender:<form:radiobuttons path="gender" items="${genders }" />
	 	<br/>
	 	deptName:<form:select path="department.id" items="${depts }" itemLabel="departmentName" itemValue="id"></form:select>
	 	
	 			<!-- <select name="department.id">
	 				<option value="1">开发部</option>
	 				<option value="2">测试部</option>
	 			</select> -->
	 	<br/>
	 	<c:if test="${flag }">
	 		<input type="submit" value="Edit"/>
 	 	</c:if>
 	 	<c:if test="${!flag }">
		 	<input type="submit" value="ADD"/>
 	 	</c:if>
	 </form:form>
</body>
</html>

3) edit.jsp

7.2 搭建开发环境

1) 拷贝jar包WebContent\WEB-INF\lib
com.springsource.net.sf.cglib-2.2.0.jar
com.springsource.org.aopalliance-1.0.0.jar
com.springsource.org.aspectj.weaver-1.6.8.RELEASE.jar
spring-aop-4.0.0.RELEASE.jar
spring-aspects-4.0.0.RELEASE.jar
commons-logging-1.1.3.jar
spring-beans-4.0.0.RELEASE.jar
spring-context-4.0.0.RELEASE.jar
spring-core-4.0.0.RELEASE.jar
spring-expression-4.0.0.RELEASE.jar
spring-jdbc-4.0.0.RELEASE.jar
spring-orm-4.0.0.RELEASE.jar
spring-tx-4.0.0.RELEASE.jar
spring-web-4.0.0.RELEASE.jar
spring-webmvc-4.0.0.RELEASE.jar
2) src-springmvc.xml

创建配置文件:springmvc.xml 增加context,mvc,beans名称空间。

<?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/mvc http://www.springframework.org/schema/mvc/spring-mvc-4.0.xsd
		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-4.0.xsd">

	<!-- 组件扫描 -->
	<context:component-scan base-package="com.atguigu.springmvc"></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>
	<!-- 
		将在 SpringMVC 上下文中定义一个 DefaultServletHttpRequestHandler,
		它会对进入 DispatcherServlet 的请求进行筛查,如果发现是没有经过映射的请求,
		就将该请求交由 WEB 应用服务器默认的 Servlet 处理,如果是由映射的请求,才由 DispatcherServlet 继续处理
		
		如果web应用服务器的默认的Serlvet的名字不叫"default",则需要通过default-servlet-name来进行指定.
		
		配置了default-serlvet-handler后,RequestMapping的映射会失效,需要加上annotation-driven的配置。		
	 -->
	<mvc:default-servlet-handler />
	<!-- 以后讲 -->
	<mvc:annotation-driven/>
</beans>

3) WebContent/WEB-INF/web.xml

配置核心控制器:web.xml

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" id="WebApp_ID" version="2.5">
  
  <!-- 字符编码过滤器 -->
  <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>
  
  <!-- REST 过滤器 -->
  <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>
		<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>
5) WebContent/index.jsp

创建相关页面

/WEB-INF/views/list.jsp

index.jsp

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<!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>	
	<a href="emps">List All Emps</a>

</body>
</html>
6) 增加实体类src/beans/Employee Department
package com.atguigu.springmvc.beans;

public class Department {

	private Integer id;
	private String departmentName;

	public Department() {
		// TODO Auto-generated constructor stub
	}
	
	public Department(int i, String string) {
		this.id = i;
		this.departmentName = string;
	}

	setter getter toString省略........
}

----------------------------------------------------------------
package com.atguigu.springmvc.beans;

public class Employee {

	private Integer id;
	private String lastName;

	private String email;
	//1 male, 0 female
	private Integer gender;
	
	private Department department;

	setter getter toString省略........

	public Employee(Integer id, String lastName, String email, Integer gender,
			Department department) {
		super();
		this.id = id;
		this.lastName = lastName;
		this.email = email;
		this.gender = gender;
		this.department = department;
	}

	public Employee() {
		// TODO Auto-generated constructor stub
	}
}

7) 增加DAO类
src/dao
package com.atguigu.springmvc.dao;

import java.util.Collection;
import java.util.HashMap;
import java.util.Map;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Repository;

import com.atguigu.springmvc.beans.Department;
import com.atguigu.springmvc.beans.Employee;


@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, "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);
	}
}
---------------------------------------------------------------------
package com.atguigu.springmvc.dao;

import java.util.Collection;
import java.util.HashMap;
import java.util.Map;

import org.springframework.stereotype.Repository;

import com.atguigu.springmvc.beans.Department;


@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);
	}
	
}

src/handler
package com.atguigu.springmvc.handler;

import java.io.IOException;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.CookieValue;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestHeader;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;

import com.atguigu.springmvc.beans.User;

@Controller
//@RequestMapping(value="/springmvc")
public class SpringmvcHandler {
	
	/**
	 * 测试原生的Servlet API
	 * @throws IOException 
	 * @throws ServletException 
	 */
	@RequestMapping("/testServletAPI")
	public void testServletAPI(HttpServletRequest request, HttpServletResponse response ) throws ServletException, IOException {
		
		System.out.println("request: " + request );  
		
		System.out.println("response: " + response ); 
		// 转发
		//request.getRequestDispatcher("/WEB-INF/views/success.jsp").forward(request, response);
		
		// 重定向  将数据写给客户端
		//response.sendRedirect("http://www.baidu.com");
		
		response.getWriter().println("Hello Springmvc ");
	}
	
	/**
	 * POJO
	 */
	@RequestMapping("/testPOJO")
	public String testPOJO(User user) {
		
		System.out.println("user:" + user);
		return "success";
	}
	
	/**
	 * @CookieValue  映射cookie信息到请求处理方法的形参中
	 */
	@RequestMapping("/testCookieValue")
	public String testCookieValue(@CookieValue("JSESSIONID")String sessionId) {
		System.out.println("sessionid:" + sessionId);
		return "success";
	}
	
	/**
	 * @RequestHeader  映射请求头信息到请求处理方法的形参中
	 */
	
	@RequestMapping("testRequestHeader")
	public String testRequestHeader(@RequestHeader("Accept-Language")String acceptLanguage) {
		System.out.println("acceptLanguage:" + acceptLanguage);
		return "success";
	}
	
	/**
	 * @RequestParam  映射请求参数到请求处理方法的形参
	 * 	 1. 如果请求参数名与形参名一致, 则可以省略@RequestParam的指定。
	 * 	 2. @RequestParam 注解标注的形参必须要赋值。 必须要能从请求对象中获取到对应的请求参数。
	 * 		可以使用required来设置为不是必须的。 
	 * 	 3. 可以使用defaultValue来指定一个默认值取代null
	 * 客户端的请求:testRequestParam?username=Tom&age=22
	 */
	@RequestMapping("/testRequestParam")
	public String testRequestParam(@RequestParam("username")String username,
							@RequestParam(value="age",required=false,defaultValue="0")int age ) {
		//web: request.getParameter()    request.getParameterMap()
		
		System.out.println(username + " , " + age);
		
		return "success";
	}
	
	
	
	/**
	 * REST PUT
	 */
	@RequestMapping(value="/order",method=RequestMethod.PUT)
	public String testRestPUT() {
		System.out.println("REST PUT");
		return "success";
	}
	/**
	 * REST POST
	 */
	@RequestMapping(value="/order",method=RequestMethod.POST)
	public String testRestPOST() {
		System.out.println("REST POST");
		
		return "success";
	}
	
	
	/**
	 * REST DELETE
	 */
	@RequestMapping(value="/order/{id}",method=RequestMethod.DELETE)
	public String testRestDELETE(@PathVariable("id")Integer id ) {
		System.out.println("REST DELETE: " + id );
		return "success";
	}
	
	/**
	 * REST GET
	 */
	@RequestMapping(value="/order/{id}",method=RequestMethod.GET)
	public String testRestGET(@PathVariable("id")Integer id ) {
		System.out.println("REST GET: " + id );
		return "success";
	}
	
	/**
	 * 带占位符的URL
	 * 
	 * 浏览器:  http://localhost:8888/Springmvc01/testPathVariable/admin/1001
	 */
	@RequestMapping(value="/testPathVariable/{name}/{id}")
	public String testPathVariable(@PathVariable("name")String name, @PathVariable("id")Integer id ) {
		System.out.println(name  + " : " + id);
		
		return "success";
	}
	
	
	/**
	 * @RequestMapping  映射请求参数   以及  请求头信息
	 * 
	 * params  : username=tom&age=22
	 * headers
	 */
	
	@RequestMapping(value="/testRequestMappingParamsAndHeaders",
					params= {"username","age=22"},
					headers= {"!Accept-Language"})
	public String testRequestMappingParamsAndHeaders() {
		
		return "success";
	}
	
	
	/**
	 * @RequestMapping  method 映射请求方式
	 * 
	 */
	@RequestMapping(value="/testRequestMappingMethod",method= {RequestMethod.POST,RequestMethod.GET})
	public String testRequestMappingMethod() {
		
		return "success";
	}
	
	/**
	 * @RequestMapping  
	 */
	@RequestMapping(value="/testRequestMapping")
	public String testRequestMapping() {
		return "success";
	}
}	

7.3 RESTRUL_CRUD_显示所有员工信息

1) 增加页面链接

<a href="empList">To Employee List</a>

2) 增加处理器

package com.atguigu.springmvc.crud.handlers;
 
import java.util.Map;
 
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
 
import com.atguigu.springmvc.crud.dao.EmployeeDao;
 
@Controller
public class EmployeeHandler {
 
    @Autowired
    private EmployeeDao employeeDao ;

    @RequestMapping("/empList")
    public String empList(Map<String,Object> map){
        map.put("empList", employeeDao.getAll());        //默认存放到request域中        
        return "list";
    } 
}

package com.atguigu.springmvc.handler;

import java.util.Collection;
import java.util.HashMap;
import java.util.Map;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;

import com.atguigu.springmvc.beans.Department;
import com.atguigu.springmvc.beans.Employee;
import com.atguigu.springmvc.dao.DepartmentDao;
import com.atguigu.springmvc.dao.EmployeeDao;

@Controller
public class RestCrudHandler {
	
	@Autowired
	private EmployeeDao employeeDao ;
	
	@Autowired
	private DepartmentDao departmentDao ;
	
	/**
	 * 修改功能: 具体的修改操作
	 */
	@RequestMapping(value = "/emp",method= RequestMethod.PUT)
	public String updateEmp(Employee employee) {
		employeeDao.save(employee);
		
		return "redirect:/emps";
	}
	
	
	/**
	 * 修改功能: 去往修改页面
	 */
	@RequestMapping(value="/emp/{id}",method=RequestMethod.GET)
	public String  toUpdatePage(@PathVariable("id")Integer id,Map<String,Object> map ) {
		//查询要修改的员工信息
		Employee employee = employeeDao.get(id);
		map.put("employee", employee);
		
		//页面中显示部门下拉列表的数据
		Collection<Department> depts = departmentDao.getDepartments();
		map.put("depts", depts);
		
		//页面中生成性别单选框的数据
		Map<String,String > genders = new HashMap<>();
		genders.put("0", "女");
		genders.put("1", "男");
		map.put("genders", genders);
		
		
		//去往修改页面
		return "input";
	}
	
	/**
	 * 删除功能
	 */
	@RequestMapping(value="/emp/{id}",method=RequestMethod.DELETE)
	public String deleteEmp(@PathVariable("id")Integer id ) {
		//删除员工
		employeeDao.delete(id);
		//重定向到列表
		return "redirect:/emps";
	}
	
	/**
	 * 添加功能 : 具体的添加操作
	 */
	@RequestMapping(value="/emp",method=RequestMethod.POST)
	public String  addEmp(Employee employee) {
		//添加员工
		employeeDao.save(employee);
		//回到列表页面 :重定向到显示所有员工信息列表的请求. 
		
		return "redirect:/emps";
	}
	
	
	/**
	 * 添加功能: 去往添加页面
	 * 
	 * 添加页面需要部门数据
	 */
	@RequestMapping(value="/emp",method=RequestMethod.GET)
	public String toAddPage(Map<String,Object> map) {
		Collection<Department> depts = departmentDao.getDepartments();
		map.put("depts", depts);
		
		//2. 构造页面中生成单选框的数据
		Map<String,String > genders = new HashMap<>();
		genders.put("0", "女");
		genders.put("1", "男");
		map.put("genders", genders);
		
		//3. 设置页面中要回显的数据
		map.put("employee", new Employee()); 
		
		return "input";
	}
			
			
			
	/**
	 * 显示所有的员工信息列表
	 */
	@RequestMapping(value="/emps",method=RequestMethod.GET)
	public String listAllEmps(Map<String,Object> map ) {
		Collection<Employee> emps = employeeDao.getAll();
		map.put("emps", emps);
		
		return "list";
	}
}

3) SpringMVC中没遍历的标签,需要使用jstl标签进行集合遍历增加jstl标签库jar包

<%@ 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>

    <c:if test="${empty requestScope.empList }">
    	对不起,没有找到任何员工!
    </c:if>
    <c:if test="${!empty requestScope.empList }">
        <table border="1" cellpadding="10" cellspacing="0">                
            <tr>
                <td>EmpId</td>
                <td>LastName</td>
                <td>Gender</td>
                <td>Email</td>
                <td>DepartmentName</td>
                <td>Edit</td>
                <td>Delete</td>
            </tr>
            <c:forEach items="${requestScope.empList }" var="emp">
                <tr>
                    <td>${emp.id }</td>
                    <td>${emp.lastName }</td>
                    <td>${emp.gender==0?"Female":"Male" }</td>
                    <td>${emp.email }</td>
                    <td>${emp.department.departmentName }</td>
                    <td><a href="">Edit</a></td>
                    <td><a href="">Delete</a></td>
                </tr>                
            </c:forEach>
        </table>
    </c:if>
 
</body>
</html>

7.4 RESTRUL_CRUD_添加操作

1) 在list.jsp上增加连接

<a href="empInput">Add Employee</a>

2) 增加处理器方法

@RequestMapping(value="/empInput",method=RequestMethod.GET)
public String empInput(Map<String,Object> map){
    map.put("deptList", departmentDao.getDepartments());
    //解决错误:java.lang.IllegalStateException: Neither BindingResult nor plain target object for bean name 'command' available as request attribute
    Employee employee = new Employee();
    //map.put("command", employee);
    map.put("employee", employee);
    return "add";
}

3) 显示添加页面

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8" import="java.util.*"%>
<%@ 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>
    </head>
    <body>

        <!-- 
1.为什么使用SpringMVC的form标签
① 快速开发
② 表单回显
2.可以通过modelAttribute指定绑定的模型属性,
若没有指定该属性,则默认从request域中查找command的表单的bean
如果该属性也不存在,那么,则会发生错误。
-->
        <form:form action="empAdd" method="POST" modelAttribute="employee">
            LastName : <form:input path="lastName"/><br><br>
            Email : <form:input path="email"/><br><br>
            <%
            Map<String,String> map = new HashMap<String,String>();
            map.put("1", "Male");
            map.put("0","Female");
            request.setAttribute("genders", map);
            %>
            Gender : <br><form:radiobuttons path="gender" items="${genders }" delimiter="<br>"/><br><br>
            DeptName : 
            <form:select path="department.id" 
                         items="${deptList }" 
                         itemLabel="departmentName" 
                         itemValue="id"></form:select><br><br>
            <input type="submit" value="Submit"><br><br>
        </form:form> 
    </body>
</html>

4) 显示表单信息时,会报错:

7.5 使用Spring的表单标签

input.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<!-- 导入Springmvc表单标签库 -->
<%@taglib prefix="form" uri="http://www.springframework.org/tags/form" %>

<!-- 导入JSTL标签库 -->
<%@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>
	<!-- Springmvc的表单标签:
			 1. 可以快速的开发表单
			 2. 可以更加方便的回显数据.
			 
		Springmvc表单标签遇到的问题:
			Neither BindingResult nor plain target object 
			for bean name 'command' available as request attribute
		
		问题原因: Springmvc的表单标签必须要进行数据的回显。 默认会使用"command"这个key到request中
		                  找回显的数据。如果找不到,则抛出异常。 
		问题解决: 让Springmvc可以通过"command"从request中找到要回显的数据. 
				还可以通过modelAttribute来指定一个key替换默认的command
				
		表单标签在最终执行时会转化成原始的HTML标签.	
	 -->
	 <form:form action="${pageContext.request.contextPath }/emp"  method="post" modelAttribute="employee">
	 	<!-- 
	 		判断是添加操作还是修改操作:
	 			根据回显的Employee对象的id值来判断: 如果有id就是修改  如果没有id就是添加操作
	 	 -->
	 	 <c:if test="${!empty employee.id }" var="flag">
	 	 		<!-- 修改操作 -->
	 	 		<form:hidden path="id"/>
	 	 		<!-- 隐藏PUT -->
	 	 		<input type="hidden" name="_method" value="PUT"/>
	 	 </c:if>
	 
	 
	 	lastName:<form:input path="lastName" /> 
         <!-- path就相当于HTML中input标签中的name属性 -->
	 			<!--  <input type="text"	 name="lastName"/> -->
	 			<br/>
	 	Email: <form:input path="email"/>
	 	<br/>
	 		 <!-- radiobuttons 可以根据Map数据来生成单选框 -->
	 	Gender:<form:radiobuttons path="gender" items="${genders }" />
	 	<br/>
	 	deptName:<form:select path="department.id" items="${depts }" itemLabel="departmentName" itemValue="id"></form:select>
         <!--itemLabel指定下拉列表的key,itemValue指定下拉列表的值-->
	 	
	 			<!-- <select name="department.id">
	 				<option value="1">开发部</option>
	 				<option value="2">测试部</option>
	 			</select> -->
	 	<br/>
	 	<c:if test="${flag }">
	 		<input type="submit" value="Edit"/>
 	 	</c:if>
 	 	<c:if test="${!flag }">
		 	<input type="submit" value="ADD"/>
 	 	</c:if>
	 </form:form>
</body>
</html>

1) 通过 SpringMVC 的表单标签可以实现将模型数据中的属性和 HTML 表单元素相绑定,以实现表单数据更便捷编辑和表单值的回显
2) form 标签
 一般情况下,通过 GET 请求获取表单页面,而通过 POST 请求提交表单页面,因此获取表单页面和提交表单页面的 URL 是相同的。
 只要满足该最佳条件的契约,form:form 标签就无需通过 action 属性指定表单提交的 URL
 可以通过 modelAttribute 属性指定绑定的模型属性,若没有指定该属性,则默认从 request 域对象中读取 command 的表单 bean,如果该属性值也不存在,则会发生错误。
3) SpringMVC 提供了多个表单组件标签,如 form:input/、form:select/ 等,用以绑定表单字段的属性值,它们的共有属性如下:
 path:表单字段,对应 html 元素的 name 属性,支持级联属性
 htmlEscape:是否对表单值的 HTML 特殊字符进行转换,默认值为 true
 cssClass:表单组件对应的 CSS 样式类名
 cssErrorClass:表单组件的数据存在错误时,采取的 CSS 样式
4) form:input、form:password、form:hidden、form:textarea:对应 HTML 表单的 text、password、hidden、textarea 标签
5) form:radiobutton:单选框组件标签,当表单 bean 对应的属性值和 value 值相等时,单选框被选中
6) form:radiobuttons:单选框组标签,用于构造多个单选框
 items:可以是一个 List、String[] 或 Map
 itemValue:指定 radio 的 value 值。可以是集合中 bean 的一个属性值
 itemLabel:指定 radio 的 label 值
 delimiter:多个单选框可以通过 delimiter 指定分隔符
7) form:checkbox:复选框组件。用于构造单个复选框
8) form:checkboxs:用于构造多个复选框。使用方式同 form:radiobuttons 标签
9) form:select:用于构造下拉框组件。使用方式同 form:radiobuttons 标签
10) form:option:下拉框选项组件标签。使用方式同 form:radiobuttons 标签
11) form:errors:显示表单组件或数据校验所对应的错误
 <form:errors path= “” /> :显示表单所有的错误
 <form:errors path= “user
” /> :显示所有以 user 为前缀的属性对应的错误
 <form:errors path= “username” /> :显示特定表单对象属性的错误

7.6 添加员工实验代码

1) 表单

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8" import="java.util.*"%>
<%@ 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>
</head>
<body>
 
<!-- 
1.为什么使用SpringMVC的form标签
① 快速开发
② 表单回显
2.可以通过modelAttribute指定绑定的模型属性,
若没有指定该属性,则默认从request域中查找command的表单的bean
如果该属性也不存在,那么,则会发生错误。
 -->
 <form:form action="empAdd" method="POST" modelAttribute="employee">
         LastName : <form:input path="lastName" /><br><br>
         Email : <form:input path="email" /><br><br>
         <%
                 Map<String,String> map = new HashMap<String,String>();
                 map.put("1", "Male");
                 map.put("0","Female");
                 request.setAttribute("genders", map);
         %>
         Gender : <br><form:radiobuttons path="gender" items="${genders }" delimiter="<br>"/><br><br>
         DeptName : 
                 <form:select path="department.id" 
                                                 items="${deptList }" 
                                                 itemLabel="departmentName" 
                                                 itemValue="id"></form:select><br><br>
                 <input type="submit" value="Submit"><br><br>
 </form:form> 
</body>
</html>


2) 控制器方法

@Controller
public class EmployeeHandler {
@RequestMapping(value="/empAdd",method=RequestMethod.POST)
public String empAdd(Employee employee){
employeeDao.save(employee);
return "redirect:/empList";
}
}


7.7 RESTRUL_CRUD_删除操作&处理静态资源

7.7.1 删除实验代码

1) 页面链接

<td><a href="/empDelete/${emp.id }">Delete</a></td>

2) 控制器方法

@RequestMapping(value="/empDelete/{id}" ,method=RequestMethod.DELETE)
public String empDelete(@PathVariable("id") Integer id){
employeeDao.delete(id);
return "redirect:/empList";
}


7.7.2 HiddenHttpMethodFilter过滤器

发起请求,无法执行,因为delete请求必须通过post请求转换为delete请求,借助:HiddenHttpMethodFilter过滤器

7.7.3 需要使用jQuery来转换请求方式

1) 加入jQuery库文件

/scripts/jquery-1.9.1.min.js

2) jQuery库文件不起作用

2)	jQuery库文件不起作用
警告: No mapping found for HTTP request with URI [/SpringMVC_03_RESTFul_CRUD/scripts/jquery-1.9.1.min.js] in DispatcherServlet with name 'springDispatcherServlet'


3) 解决办法,SpringMVC 处理静态资源

① 为什么会有这样的问题:

优雅的 REST 风格的资源URL 不希望带 .html 或 .do 等后缀,若将 DispatcherServlet 请求映射配置为 /, 则 Spring MVC 将捕获 WEB 容器的所有请求, 包括静态资源的请求, SpringMVC 会将他们当成一个普通请求处理, 因找不到对应处理器将导致错误。

②解决: 在 SpringMVC 的配置文件中配置 mvc:default-servlet-handler/

4) 配置后,原来的请求又不好使了

​ 需要配置<mvc:annotation-driven />

7.7.4 关于<mvc:default-servlet-handler/>作用

<!-- 
<mvc:default-servlet-handler/> 将在 SpringMVC 上下文中定义一个 DefaultServletHttpRequestHandler,
它会对进入 DispatcherServlet 的请求进行筛查,如果发现是没有经过映射的请求,
就将该请求交由 WEB 应用服务器默认的 Servlet 处理,如果不是静态资源的请求,才由 DispatcherServlet 继续处理
一般 WEB 应用服务器默认的 Servlet 的名称都是 default。
若所使用的 WEB 服务器的默认 Servlet 名称不是 default,则需要通过 default-servlet-name 属性显式指定        
参考:CATALINA_HOME/config/web.xml
    <servlet>
        <servlet-name>default</servlet-name>
        <servlet-class>org.apache.catalina.servlets.DefaultServlet</servlet-class>
        <init-param>
            <param-name>debug</param-name>
            <param-value>0</param-value>
        </init-param>
        <init-param>
            <param-name>listings</param-name>
            <param-value>false</param-value>
        </init-param>
        <load-on-startup>1</load-on-startup>
    </servlet>
该标签属性default-servlet-name默认值是"default",可以省略。        
<mvc:default-servlet-handler/>        
 -->
<mvc:default-servlet-handler default-servlet-name="default"/>


7.7.5 通过jQuery转换为DELETE请求

<td><a class="delete" href="empDelete/${emp.id }">Delete</a></td>

<form action="" method="post">
<input type="hidden" name="_method" value="DELETE"/>
</form>


<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>


7.7.6 删除操作流程图解

7.8 RESTRUL_CRUD_修改操作

7.8.1 根据id查询员工对象,表单回显

1) 页面链接

<td><a href="empEdit/${emp.id }">Edit</a></td>

2) 控制器方法

//修改员工 - 表单回显
@RequestMapping(value="/empEdit/{id}",method=RequestMethod.GET)
public String empEdit(@PathVariable("id") Integer id,Map<String,Object> map){
map.put("employee", employeeDao.get(id));
map.put("deptList",departmentDao.getDepartments());
return "edit";
}


3) 修改页面

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8" import="java.util.*"%>
<%@ 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.为什么使用SpringMVC的form标签
① 快速开发
② 表单回显
2.可以通过modelAttribute指定绑定的模型属性,
若没有指定该属性,则默认从request域中查找command的表单的bean
如果该属性也不存在,那么,则会发生错误。
修改功能需要增加绝对路径,相对路径会报错,路径不对
 -->
 <form:form action="${pageContext.request.contextPath }/empUpdate" 
method="POST" modelAttribute="employee">                        
<%--
         LastName : <form:input path="lastName" /><br><br>
          --%>
                 <form:hidden path="id"/>
                 <input type="hidden" name="_method" value="PUT">
                 <%-- 这里不要使用form:hidden标签,否则会报错。 
<form:hidden path="_method" value="PUT"/>
                         Spring的隐含标签,没有value属性,同时,path指定的值,在模型对象中也没有这个属性(_method),所以回显时会报错。
                         org.springframework.beans.NotReadablePropertyException: 
                         Invalid property '_method' of bean class [com.atguigu.springmvc.crud.entities.Employee]: 
                         Bean property '_method' is not readable or has an invalid getter method: 
                         Does the return type of the getter match the parameter type of the setter?
                  --%>
                          
         Email : <form:input path="email" /><br><br>
         <%
                 Map<String,String> map = new HashMap<String,String>();
                 map.put("1", "Male");
                 map.put("0","Female");
                 request.setAttribute("genders", map);
         %>
         Gender : <br><form:radiobuttons path="gender" items="${genders }" delimiter="<br>"/><br><br>
         DeptName : 
                 <form:select path="department.id" 
                                                 items="${deptList }" 
                                                 itemLabel="departmentName" 
                                                 itemValue="id"></form:select><br><br>
                 <input type="submit" value="Submit"><br><br>
 </form:form>
</body>
</html>


7.8.2 提交表单,修改数据

1) 控制器方法

@RequestMapping(value="/empUpdate",method=RequestMethod.PUT)
public String empUpdate(Employee employee){
employeeDao.save(employee);              
return "redirect:/empList";
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值