RESTful-CRUD需求
显示所有员工信息(不连接数据库)
- 搭建环境
- 编写web.xml文件
<?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_4_0.xsd"
version="4.0">
<!--配置DispatcherServlet
用户分发请求路径操作
-->
<servlet>
<servlet-name>dispatcherServlet</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<!--配置SpringMVC的配置文件-->
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:springmvc-cfg.xml</param-value>
</init-param>
</servlet>
<servlet-mapping>
<servlet-name>dispatcherServlet</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
<!--配置将POST请求转换为DELETE 和 PUTS 请求的过滤器-->
<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>
<!--配置编码过滤-->
<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>
<init-param>
<param-name>forceEncoding</param-name>
<param-value>true</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>characterEncodingFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
</web-app>
- 配置springmvc-cfg.xml文件
<?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">
<!--配置springmvc IOC容器扫描基包-->
<context:component-scan base-package="mao.shu.springmvc.crud"/>
<!--配置视图解析器-->
<bean id="viewResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<!--视图前缀-->
<property name="prefix" value="/WEB-INF/views/"/>
<!--视图后缀-->
<property name="suffix" value=".jsp"/>
</bean>
</beans>
-
创建实体类:
- Employee(雇员)
- Department(部门)
-
Employee类
public class Employee {
private Integer id;
private String lastName;
private String email;
private Integer gender;
private Department department;
//getter和setter方法
}
- Department类
public class Department {
private Integer id;
private String departmentName;
//getter和setter方法
}
-
编写DAO类:由于此次没有连接数据库所以使用静态的数据
- EmployeeDAO
- DepartmentDAO
-
EmployeeDAO
package mao.shu.springmvc.crud.dao;
import mao.shu.springmvc.crud.vo.Department;
import mao.shu.springmvc.crud.vo.Employee;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Repository;
import java.util.Collection;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
@Repository
public class EmployeeDAO {
@Autowired
private DepartmentDAO departmentDAO;
//使用Map集合保存数据
private static Map<Integer, Employee> employees = null;
static {
employees = new HashMap<>();
for (int i = 0; i < 10; i++) {
int gender = i % 2 == 0 ? 1 : 0;
employees.put(1000 + i,
new Employee(1000 + i,
"xiemaoshu" + i,
"14199@qq.com" + i,
gender,
new Department(7890 + i,
"开发部" + i)));
}
}
/**
* 获取全部的雇员信息
* @return
*/
public Collection<Employee> getAll(){
return this.employees.values();
}
}
- 编写映射请求方法
@Controller
public class EmployeeHandler {
@Autowired
private EmployeeDAO employeeDAO;
@RequestMapping
public String list(Map<String,Object> map){
map.put("employees",this.employeeDAO.getAll());
return "emp_list";
}
}
- 编写jsp显示页面
<body>
<c:if test="${empty requestScope.employees}">
<h1>没有任何雇员信息</h1>
</c:if>
<table border="1" >
<tr>
<td>雇员id</td>
<td>雇员名称</td>
<td>雇员邮箱</td>
<td>性别</td>
<td>部门信息</td>
<td>修改</td>
<td>删除</td>
</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?'女':'男'}</td>
<td>${emp.department.departmentName}</td>
<td><a href="">修改</a> </td>
<td><a href="">删除</a></td>
</tr>
</c:forEach>
</table>
</body>
- 发布项目,测试
添加操作和表单标签
- 添加员工信息页面显示效果
- 本次表单使用SpringMVC的表单标签完成
- 添加完成之后使页面重定向到emp_list.jsp页面
实现雇员添加
- 在EmployeeDAO中添加一个雇员增加方法
private static Integer startEmpid = 10;
/**
* 进行雇员添加操作
* @param vo
* @return
*/
public boolean add(Employee vo){
vo.setId(this.startEmpid++);
Department dept = this.departmentDAO.get(vo.getDepartment().getId());
vo.setDepartment(dept);
this.employees.put(vo.getId(),vo);
return true;
}
- 在EmployeeHandler类中添加一个雇员添加映射路径方法和一个雇员添加页面显示方法
- 这两个方法都使用"/emp"作为映射路径,但是显示页面的方法使用"GET"请求,添加操作使用"POST"请求以作为区分
@Autowired
private DepartmentDAO departmentDAO;
/**
* 显示雇员的添加页面
* 将雇员字段和部门信息保存到请求域之中
* 供添加表单显示操作
* @param map
* @return
*/
@RequestMapping(value="/emp",method = RequestMethod.GET)
public String savePre(Map<String,Object> map){
map.put("employee",new Employee());
map.put("department",this.departmentDAO.getAll());
return "emp_add";
}
/**
* 显示雇员添加表单操作方法使用GET请求
* @param vo
* @return
*/
@RequestMapping(value="/emp",method=RequestMethod.POST)
public String save(Employee vo){
this.employeeDAO.add(vo);
return "redirect:empList";
}
- 编写DepartmentDAO
@Repository
public class DepartmentDAO {
//使用Map集合保存数据
private static Map<Integer, Department> departments= null;
static {
departments = new HashMap<>();
for (int i = 0; i < 10; i++) {
int gender = i % 2 == 0 ? 1 : 0;
departments.put(7890 + i,
new Department(7890+i,"开发部"+i));
}
}
public Collection<Department> getAll(){
return this.departments.values();
}
public Department get(Integer deptno){
return this.departments.get(deptno);
}
}
- 定义emp_add.jsp页面
- 需要使用到SpringMVC的表单标签,在页面中需要导入标签
<%@ taglib prefix="from" uri="http://www.springframework.org/tags/form" %>
- 如果使用表单标签出现乱码的情况,可以在tomcat的配置文件"server.xml"文件中的<Connector>标签中配置编码
<Connector URIEncoding="UTF-8" port="8080" protocol="HTTP/1.1"
connectionTimeout="20000"
redirectPort="8443" />
- emp_add.jsp页面
<body>
<%--
使用SpringMVC的表单标签
modelAttribute 属性描述的是表单的Bean属性,
表单标签会根据modelAttribute提供的值在request中寻找对应的属性,
如果没有指定modelAttribute 则会在request中寻找名为"command"的属性,
如果也没有找到"command"的属性则会抛出异常
--%>
<form:form action="${pageContext.request.contextPath}/emp" method="POST" modelAttribute="employee">
雇员名称:<form:input path="lastName"/><br/>
雇员邮箱<form:input path="email"/><br/>
<%
Map<String, String> genders = new HashMap<>();
genders.put("0", "女");
genders.put("1", "男");
request.setAttribute("genders", genders);
%>
性别:<form:radiobuttons path="gender" items="${genders}"/><br/>
部门:<form:select path="department.id" items="${departments}" itemLabel="departmentName" itemValue="id"></form:select>
<br/>
<input type="submit" value="提交"/>
</form:form>
</body>
- 测试:
删除操作和处理静态资源
处理静态资源
- 静态资源:例如js文件,或者css样式文件或者一个图片,这样的文件都属于静态资源.
- 当使用SpringMVC的时候,配置了DispatcherServlet之后,当要访问这些静态资源时,SpringMVC会将静态资源当作一个请求,如果没有找到对应的处理请求,则无法加载静态资源
- 当直接访问静态资源的时候,会出现以下的警告信息
解决方法
- 如果配置了<mvc:default-servlet-handler/> 则SpringMVC的@RequestMapping注解映射的路径就会失效因此需要配置<mvc:annotation-driven conversion-service=“conversionService”>这个标签来使@RequestMapping注解生效
- 示例:配置SpringMVC配置文件
<!--配置默认的请求处理-->
<mvc:default-servlet-handler/>
<!--
如果配置了<mvc:default-servlet-handler/>
则SpringMVC的@RequestMapping注解映射的路径就会失效
因此需要配置<mvc:annotation-driven conversion-service="conversionService">这个标签
来使@RequestMapping注解生效
-->
<mvc:annotation-driven ></mvc:annotation-driven>
实现雇员删除操作
- 在EmployeeDAO中 添加一个雇员删除操作
public boolean delete(Integer id){
return this.employees.remove(id) != null;
}
- 在EmployeeHandler类中添加一个删除的映射请求
- 使用占位符的方式接收id值
- 方式采用DELETE方式
@RequestMapping(value="/emp/{id}",method={RequestMethod.DELETE})
public String remove(@PathVariable("id") Integer id){
this.employeeDAO.delete(id);
return "redirect:/empList";
}
- 修改emp_list.jsp页面,修改删除字段,添加删除操作路径
<td><a href="emp/${emp.id}">删除</a></td>
- 此时使用超链接的方式发送删除请求,默认是GET请求,需要将超链接的GET请求转换为DELETE请求.
- 使用JavaScript的方式转换
<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");
//替换表单的提交请求,并进行提交
$("#deleteFrom").attr("action",href).submit();
return false;//阻止超链接提交
});
})
</script>
<%--
利用JavaScript将表单的POST请求转换为DELETE请求
标签:<input type="hidden" name="_method" value="DELETE"/>
的作用是用于SpringMVC的HiddenHttpMethodFilter过滤器使用
--%>
<form id="deleteFrom" action="" method="post">
<input type="hidden" name="_method" value="DELETE"/>
</form>
- 测试
修改操作
- 雇员的修改页面和添加页面都是用同一个jsp页面
- 雇员的修改操作,使用PUT 类型请求方法
- 在emp_list.jsp页面之中添加修改超链接,使用超链接默认的get请求即可
<td><a href="emp/${emp.id}">修改</a></td>
- 在EmployeeHandler类中添加一个显示修改操作页面的方法,修改页面和添加页面使用同样的jsp页面
- 添加一个修改操作的方法,修改操作方法使用"PUT"类型的方法
- 因为雇员的lastName字段不允许被修改,所以页面之中不会提供lastName字段的操作,因此在修改方法上接收的Employee参数中lastName是空的,需要定义一个"@ModelAttribute"方法,只执行修改操作之前查询处要修改的雇员信息,而后将查询出的Employee对象和修改方法中的Employee
@RequestMapping(value = "/emp/{id}", method = RequestMethod.GET)
public String editPre(@PathVariable("id") Integer id, Map<String, Object> map) {
map.put("employee", this.employeeDAO.get(id));
map.put("department", this.departmentDAO.getAll());
return "emp_input";
}
@RequestMapping(value="/emp",method = RequestMethod.PUT)
public String edit(Employee employee) {
this.employeeDAO.add(employee);
return "redirect:/empList";
}
@ModelAttribute
public void getEmployee(@RequestParam(value="id",required = false) Integer id,
Map<String,Object> map){
Employee employee = this.employeeDAO.get(id);
map.put("employee",employee);
}
- 在EmployeeDAO中添加一个get()方法,用户取得某个雇员信息
public Employee get(Integer id) {
return this.employees.get(id);
}
- 修改emp_input.jsp页面,修改"LastName"字段
- 并且如果employee.id值不等null表示进行修改操作,需要将表单的POST请求改为PUT请求
<c:if test="${employee.id == null}">
雇员名称:<form:input path="lastName"/><br/>
</c:if>
<c:if test="${employee.id != null}">
<form:hidden path="id"/>
<%--
<input type="hidden" name="_method" value="PUT"/>
该标签用于给SpringMVC的HiddenMethoderFilter 过滤器将POST请求转换为PUT请求
这里不能够使用<form:hidden> 标签进行转换,因为<form:hidden> 默认于模型中的字段所对应
如果使用<form:hidden> 标签作为PUT方法的标识,则SpringMVC会在请求的模型参数中寻找定义的字段
如果没有找到就会报错
--%>
<input type="hidden" name="_method" value="PUT"/>
</c:if>
- 测试