SpringMVC-Restful的CRUD

一.简介

利用SpringMVC来做一个关于员工信息的CRUD(增删改查),符合Rest风格的。

  • C:Create 创建
  • R:Retrieve 查询
  • U:Update 更新
  • D:Delete 删除

原本是连接数据库保存数据,但是现在使用Map,List保存数据之类的。

1.1 搭建开发环境

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.增减实体类

SpringMVC-Restful的CRUD_第1张图片  SpringMVC-Restful的CRUD_第2张图片

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:查询所有员工

2.1 员工列表展示(查询所有员工)

流程:访问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页面显示:

SpringMVC-Restful的CRUD_第3张图片

2.2 添加员工

流程:在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表单,取值麻烦

员工添加

lastName:
email:
gender:
男:
女:
dept:

(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-Restful的CRUD_第4张图片

SpringMVC认为,表单数据中的每一项最终是要回显的,path指定的是一个属性,这个属性是从隐含模型(请求域中取出的某个对象中的属性)。请求域中必须有这个对象,拥有这个属性,这个对象就是请求域中的command对象。

解决方法一:在处理方法中,向请求域中添加conmand对象,表单标签会从请求域中获取一个command对象,把这个对象中的每一个属性对应的显示出来。

	model.addAttribute("command", new Employee(null,"张三","qq.com",0,departmentDao.getDepartment(101)));

显示为:

SpringMVC-Restful的CRUD_第5张图片

解决方法二: 解决方法一回显的是一个员工的值,不需要显示出来这些东西。可以告诉SpringMVC不要去取command值,做了一个modelAttribute指定的值,取对象时用的key就用modelAttribute指的值。

	model.addAttribute("employee", new Employee());

     
    lastName:
    email:
    gender:
男:
女:
dept:

显示为:

SpringMVC-Restful的CRUD_第6张图片

4.点击保存,表单标签的处理方式为:

添加处理方法,因为添加完后要显示所有员工,所以使用重定向到员工列表页面。

	@RequestMapping(value="/emp",method=RequestMethod.POST)
	public String addEmp(Employee employee){
		System.out.println("要添加的员工"+employee);
		employeeDao.save(employee);
		//重定向查询全部员工
		return "redirect:/emps";
	}

总结:

Spring的表单标签:

  • 一般情况下,通过GET请求获取表单页面,而通过POST请求提交页面,因此获取表单页面和提交表单页面的URL是相同的。
  • 只要满足该最佳条件的契约,标签就无需通过action属性指定表单提交的URL。
  • 可以通过modelAttribute属性指定绑定的模型属性,若没有指定该属性,则默认从request域对象中读取command的表单bean,如果该属性值也不存在,则会发生错误。

SpringMVC提供了多个表单组件标签,如等,用以绑定表单字段的属性值,共有属性如下:

  • path:表单字段,对应html元素的name属性,支持级联属性。
  • htmlEscape:是否对表单值的HTML特殊字符进行转换,默认值为true。
  • cssClass:表单组件对应的CSS样式类名
  • cssErrorClass:表单组件的数据存在错误时,采取的CSS样式。
  • form:input、form:password、form:hidden、form:textarea:对应 HTML 表单的 text、password、hidden、textarea 标签
  • form:radiobutton:单选框组件标签,当表单 bean 对应的属性值和 value 值相等时,单选框被选中
  • form:checkbox:复选框组件。用于构造单个复选框
  • form:checkboxs:用于构造多个复选框。使用方式同 form:radiobuttons 标签
  • form:select:用于构造下拉框组件。使用方式同 form:radiobuttons 标签
  • form:option:下拉框选项组件标签。使用方式同 form:radiobuttons 标签
  • form:errors:显示表单组件或数据校验所对应的错误。

2.3 修改员工

流程图:点击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:

页面显示为:

SpringMVC-Restful的CRUD_第7张图片

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。

2.4 删除员工

流程:发送删除请求(/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)显示结果:

SpringMVC-Restful的CRUD_第8张图片

解决方法二:使用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)流程图解:

SpringMVC-Restful的CRUD_第9张图片

你可能感兴趣的:(SpringMVC)