利用SpringMVC来做一个关于员工信息的CRUD(增删改查),符合Rest风格的。
原本是连接数据库保存数据,但是现在使用Map,List保存数据之类的。
1.导包
2.写配置
(1)配置web.xml,写前端控制器,字符过滤器和支持Rest风格的过滤器
6.Spring_crud
index.html
index.htm
index.jsp
default.html
default.htm
default.jsp
springDispatcherServlet
org.springframework.web.servlet.DispatcherServlet
contextConfigLocation
classpath:springmvc.xml
1
springDispatcherServlet
/
CharacterEncodingFilter
org.springframework.web.filter.CharacterEncodingFilter
encoding
utf-8
forceEncoding
true
CharacterEncodingFilter
/*
HiddenHttpMethodFilter
org.springframework.web.filter.HiddenHttpMethodFilter
HiddenHttpMethodFilter
/*
(2)编写SpringMVC配置文件,增减context名称空间进行组件扫描,配置视图解析器。
3.增减实体类
4.增加Dao类
(1)DepartmentDao :
package com.test.dao;
import java.util.Collection;
import java.util.HashMap;
import java.util.Map;
import org.springframework.stereotype.Repository;
import com.test.bean.Department;
/*
* 部门
*/
@Repository
public class DepartmentDao {
private static Map departments = null;
static{
departments = new HashMap();
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 getDepartments(){
return departments.values();
}
/*
* 按照部门id查询
*/
public Department getDepartment(Integer id){
return departments.get(id);
}
}
(2)EmployeeDao :
package com.test.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.test.bean.Department;
import com.test.bean.Employee;
/*
* EmplyoeeDao:
*/
@Repository
public class EmployeeDao {
private static Map employees = null;
@Autowired
private DepartmentDao departmentDao;
static{
employees = new HashMap();
employees.put(1001, new Employee(1001, "E-AA", "[email protected]", 1, new Department(101, "D-AA")));
employees.put(1002, new Employee(1002, "E-BB", "[email protected]", 1, new Department(102, "D-BB")));
employees.put(1003, new Employee(1003, "E-CC", "[email protected]", 0, new Department(103, "D-CC")));
employees.put(1004, new Employee(1004, "E-DD", "[email protected]", 0, new Department(104, "D-DD")));
employees.put(1005, new Employee(1005, "E-EE", "[email protected]", 1, new Department(105, "D-EE")));
}
//初始id
private static Integer initId = 1006;
/*
* 员工保存/员工更新
*/
public void save(Employee employee){
if(employee.getId() == null){
employee.setId(initId++);
}
//根据部门id单独查出部门信息设置到员工对象中
employee.setDepartment(departmentDao.getDepartment(employee.getDepartment().getId()));
employees.put(employee.getId(), employee);
}
//查询所有员工
public Collection getAll(){
return employees.values();
}
//按照id查询
public Employee get(Integer id){
return employees.get(id);
}
//删除
public void delete(Integer id){
employees.remove(id);
}
}
因为要完成的是Restful风格的增删改查,所以增删改查的地址是:/资源名/资源标识。如下
/emp/1 GET:查询id为1的员工
/emp/1 PUT:更新id为1的员工
/emp/1 DELETE:删除id为1的员工
/emp POST:新增员工
/emps GET:查询所有员工
流程:访问index.jsp页面--->发送请求/emps--->控制器查出所有员工-->放在请求域中-->转发到emplist页面进行展示
1.index.jsp:编写页面链接
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
Insert title here
查询所有员工列表
2.增加处理器
package com.test.controller;
import java.util.Collection;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
import com.test.bean.Employee;
import com.test.dao.EmployeeDao;
@Controller
public class EmployeeController {
//自动注入
@Autowired
EmployeeDao employeeDao;
/*
* 查询所有员工
*/
@RequestMapping("/emps")
public String getEmps(Model model){
Collection empAll=employeeDao.getAll();
model.addAttribute("emps", empAll); //数据默认放在请求域中
return "emplist";
}
}
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" %>
员工列表
员工列表
ID
lastName
email
gender
departmentName
EDIT
DELETE
${emp.id }
${emp.lastName }
${emp.email }
${emp.gender==0?"女":"男"}
${emp.department.departmentName }
EDIT
DELETE
4.emplist页面显示:
流程:在emplist页面点击员工添加--->查询所有的部门信息展示在添加页面-->来到员工添加页面(add.jsp)-->输入员工数据-->点击保存-->处理器收到员工保存请求(保存员工)-->保存完成后还是来到列表页面。
1.在emplist上添加链接:
添加员工
2.增加处理器方法,因为部门信息要回显到页面中,所以要获取部门信息放到隐含模型中:
/*
* 去员工添加页面,去页面之前需要查询所有部门信息,进行展示
*/
@RequestMapping("/toaddpage")
public String toAddPage(Model model){
//1.先查询所有部门
Collection departsments=departmentDao.getDepartments();
//2.放在请求域中
model.addAttribute("depts", departsments);
return "add";
}
3.添加页面:
(1)单纯的form表单,取值麻烦
员工添加
(2)使用SpringMVC的表单标签,可以实现将模型数据中的属性和HTML表单元素相绑定,以实现表单数据更便捷编辑和表单值回显。
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%@taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<%@taglib prefix="form" uri="http://www.springframework.org/tags/form" %>
Insert title here
员工添加
lastName:
email:
gender:
男:
女:
dept:
跳转到这个添加页面时,会报错,请求域中没有一个command类型的对象。
SpringMVC认为,表单数据中的每一项最终是要回显的,path指定的是一个属性,这个属性是从隐含模型(请求域中取出的某个对象中的属性)。请求域中必须有这个对象,拥有这个属性,这个对象就是请求域中的command对象。
解决方法一:在处理方法中,向请求域中添加conmand对象,表单标签会从请求域中获取一个command对象,把这个对象中的每一个属性对应的显示出来。
model.addAttribute("command", new Employee(null,"张三","qq.com",0,departmentDao.getDepartment(101)));
显示为:
解决方法二: 解决方法一回显的是一个员工的值,不需要显示出来这些东西。可以告诉SpringMVC不要去取command值,做了一个modelAttribute指定的值,取对象时用的key就用modelAttribute指的值。
model.addAttribute("employee", new Employee());
lastName:
email:
gender:
男:
女:
dept:
显示为:
4.点击保存,表单标签的处理方式为:
添加处理方法,因为添加完后要显示所有员工,所以使用重定向到员工列表页面。
@RequestMapping(value="/emp",method=RequestMethod.POST)
public String addEmp(Employee employee){
System.out.println("要添加的员工"+employee);
employeeDao.save(employee);
//重定向查询全部员工
return "redirect:/emps";
}
Spring的表单标签:
SpringMVC提供了多个表单组件标签,如
流程图:点击EDIT-->查出要修改的员工信息放到请求域中(发送/emp/id请求 GET)-->来到修改页面(edit.jsp)进行回显-->输入完成数据,点击修改按钮(/emp/id PUT)--->修改员工信息(ModelAttribute提前查询员工)---->来到列表页面
1.页面链接
edit
2.处理器方法:
/*
* 查询员工,来到修改页面
*/
@RequestMapping(value="/emp/{id}",method=RequestMethod.GET)
public String getEmp(@PathVariable("id")Integer id,Model model){
//1.查出员工信息
Employee em=employeeDao.get(id);
//2.放在请求域中
model.addAttribute("employee", em);
//3.查出部门信息放到隐含模型中
Collection departments=departmentDao.getDepartments();
model.addAttribute("depts", departments);
return "edit";
}
3.edit.jsp页面,显示员工信息
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%@taglib uri="http://www.springframework.org/tags/form" prefix="form"%>
Insert title here
员工修改页面
email:
gender:
男:
女:
dept:
页面显示为:
4.提交表单,修改员工信息
(1)表单的action,要注意是绝对路径
<%
pageContext.setAttribute("ctp", request.getContextPath());
%>
员工修改页面
email:
gender:
男:
女:
dept:
(2)处理器方法:修改员工,我们可以知道的是这个要修改的员工信息被封装成一个Employee对象,但是修改页面中有些信息是没有的,例如员工的id和员工姓名。可以用在页面使用隐藏域来传递id,然后可以写一个ModelAttribute提前查询员工姓名。
/*
* 修改员工
*/
@RequestMapping(value="/emp/{id}",method=RequestMethod.PUT)
public String updateEmp(Employee employee,@PathVariable("id")Integer id){
System.out.println("要修改的员工"+employee);
employeeDao.save(employee);
return "redirect:/emps";
}
/*
*
* 提前查询员工
* 不能使用@PathVariable("id")Integer id,因为这个方法在所有方法之前都会执行,有些请求没有带id,会抛出异常
*/
@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);
}
}
注意:
(1)发送修改请求的时候,也可以不需要带id。因为id放在了隐藏域中(请求域中),可以在ModelAttribute中获取到。
(2)一定要注意在提前运行ModelAttribute方法时,判断id是否为null。
流程:发送删除请求(/emp/id DELETE)-->删除员工-->来到列表页面
删除链接:发起请求,无法执行,因为delete请求必须通过post请求转换为delete请求。
解决方法一:
(1)使用form表单
(2)处理器方法:
@RequestMapping(value="emp/{id}",method=RequestMethod.DELETE)
public String deleteEmp(@PathVariable("id")Integer id){
employeeDao.delete(id);
return "redirect:/emps";
}
(3)显示结果:
解决方法二:使用JQuery来转换请求方式。
(1)加入jquery库文件:scripts/jquery-1.9.1.min.js。
这个文件可能会出现问题:优雅的 REST 风格的资源URL 不希望带 .html 或 .do 等后缀,若将 DispatcherServlet 请求映射配置为 /,则 Spring MVC 将捕获 WEB 容器的所有请求, 包括静态资源的请求, SpringMVC 会将他们当成一个普通请求处理,因找不到对应处理器将导致错误。在配置文件中配置
(2)通过JQuery来转换delete请求
...
delete
...
(3)处理器方法不变
(4)流程图解: