利用SpringMVC做一个CRUD符合Rest风格的网站案例
- Web环境搭建
- 1.导入相关坐标
- 2.web.xml进行配置
- Tips: 字符编码的Filter配置要在支持REST风格的filter配置之前
- 3.SpringMVC.xml配置
- 数据库环境搭建
- 1.propertise配置文件
- 2.在Spring容器中引入pro配置文件,配置数据源,配置JDBCTemplate对象
- Dao层
- POJO---自定义对象层
- 展示所有员工的界面设计思路
- 添加员工
- Spring表单标签技术
- 需要在最上面导入Spring提供的标签库
- 好处
- spring标签库,替换上面的html写的form表单
- 注意:SpringMVC认为,表单数据中的每一项最终都是要回显的
- path指定的是一个属性,这个属性是从隐含模型(请求域)中取出的某个对象中的属性
- path指定的每一个属性,请求域中必须有一个对象,拥有这个属性
- 这个对象就是请求域中的command的值,没有就报错,错误如下:
- 在隐含模型中放入command对象
- 以前我们表单标签会从请求域中获取一个command对象,把这个对象中每一个属性对应的显示在页面上
- 可以告诉SpringMVC不要去取command的值了,我放了一个modelAttribute指定的值,取对象用的key就使用我modelAttribute指定的
- 演示:
- 点击提交按钮,对数据进行保存
- 以后jsp页面什么form表单的action提交路径,a标签的herf属性都写绝对路径,因此需要先获取项目根路径
- 处理表单提交请求的方法
- 修改员工
- 注意:被@ModelAttribute注解的方法会在所有的controller方法执行之前执行,即每一个controller方法执行之前,都会执行该方法
- 被@ModelAttribute注解的方法和目标controller方法用的都是一套的resolve方法,因此目标方法里面能写什么,获取什么,注解方法里面也能写和获取对应的内容
- 这里逻辑有一个小bug,部门的种类应该单独创建一个类,而不是按照扫描当前数据库所有员工获取所有的部门种类,这里懒的改了
- 删除功能实现
- 最终完整源码呈现
- 目录结构
- web.xml
- index.jsp
- addPages.jsp
- add.jsp
- list.jsp
- jdbc.properties
- SpringMVC.xml
- EmployeeController
- EmployeeDao
- Employee
Web环境搭建
1.导入相关坐标
代码语言:javascript复制 <!--导入spring的坐标-->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>5.0.5.RELEASE</version>
</dependency>
<!--导入aspectj的坐标-->
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjweaver</artifactId>
<version>1.8.4</version>
</dependency>
<!--引入Spring测试坐标-->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-test</artifactId>
<version>5.0.5.RELEASE</version>
</dependency>
<!--junit坐标-->
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.13.1</version>
</dependency>
<!--mysql驱动的坐标-->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.32</version>
</dependency>
<!--c3p0数据库连接池的坐标-->
<dependency>
<groupId>c3p0</groupId>
<artifactId>c3p0</artifactId>
<version>0.9.1.2</version>
</dependency>
<!--druid数据库连接池坐标-->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid</artifactId>
<version>1.1.10</version>
</dependency>
<!--spring jdbc的坐标-->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-jdbc</artifactId>
<version>5.0.5.RELEASE</version>
</dependency>
<!--spring tx的坐标,处理事务的-->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-tx</artifactId>
<version>5.0.5.RELEASE</version>
</dependency>
<!--SpringWeb模块相关的坐标-->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-web</artifactId>
<version>5.0.5.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>5.0.5.RELEASE</version>
</dependency>
<!--servlet的坐标-->
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>servlet-api</artifactId>
<version>2.5</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>javax.servlet.jsp</groupId>
<artifactId>jsp-api</artifactId>
<version>2.0</version>
<scope>provided</scope>
</dependency>
<!--jstl的依赖-->
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>jstl</artifactId>
<version>1.2</version>
</dependency>
<!--standard的依赖-->
<dependency>
<groupId>taglibs</groupId>
<artifactId>standard</artifactId>
<version>1.1.2</version>
</dependency>
2.web.xml进行配置
Tips: 字符编码的Filter配置要在支持REST风格的filter配置之前
代码语言:javascript复制<!--配置springmcv的前段控制器-->
<servlet>
<servlet-name>DispatcherServlet</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<!--SpringMvc.xml是前段控制器需要使用-->
<!--sevlet的初始化参数-->
<!--contextConfigLocation:指定SpringMVC配置文件的位置-->
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:SpringMVC.xml</param-value>
</init-param>
<!--默认第一次访问时创建对象,这里填入1,表示服务器启动时创建镀锡-->
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>DispatcherServlet</servlet-name>
<!--
/和/*都是拦截所有请求,但是/*的范围更大,还会拦截到*.jsp这些请求
一旦拦截jsp页面就不会显示了
/会拦截所有请求,但是不会拦截*.jsp,能保证jsp访问正常
-->
<url-pattern>/</url-pattern>
</servlet-mapping>
<!--配置一个字符编码的Filter-->
<filter>
<filter-name>CharacterEncodingFilter</filter-name>
<filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>
<!--初始化参数-->
<!--encoding:指定解决POST请求的乱码-->
<init-param>
<param-name>encoding</param-name>
<param-value>UTF-8</param-value>
</init-param>
<!--forceEncoding:顺手解决响应乱码
response.setCharacterEncoding(this.encoding)-->
<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>
<!--支持REST风格的filter-->
<!--配置filter-->
<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>
3.SpringMVC.xml配置
代码语言:javascript复制<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:mvc="http://www.springframework.org/schema/mvc"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
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
http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc.xsd">
<mvc:annotation-driven />
<!--context的组件扫描,需要引入context命名空间-->
<!--只需要扫描cotroller包下的内容-->
<context:component-scan base-package="com"/>
<!--视图解析器-->
<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="prefix" value="/WEB-INF/pages/"/>
<property name="suffix" value=".jsp"/>
<!--指定创建jstlView-->
<!-- <property name="viewClass" value="org.springframework.web.servlet.view.JstlView"/>-->
</bean>
</beans>
数据库环境搭建
1.propertise配置文件
代码语言:javascript复制jdbc.driver=com.mysql.jdbc.Driver
jdbc.url=jdbc:mysql://localhost:3306/tx
jdbc.username=root
jdbc.password=xxxxxxx
2.在Spring容器中引入pro配置文件,配置数据源,配置JDBCTemplate对象
SpringMVC.xml
代码语言:javascript复制 <!--加载jdbc.properties-->
<!--引入context命名空间-->
<context:property-placeholder location="classpath:jdbc.properties"/>
<!--数据源对象-->
<bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource">
<property name="driverClass" value="${jdbc.driver}"/>
<property name="jdbcUrl" value="${jdbc.url}"/>
<property name="user" value="${jdbc.username}"/>
<property name="password" value="${jdbc.password}"/>
</bean>
<!--jdbc模板对象-->
<bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate">
<property name="dataSource" ref="dataSource"/>
</bean>
Dao层
EmployeeDao类:
代码语言:javascript复制@Repository
public class EmployeeDao {
@Autowired //按照类型注入
JdbcTemplate jdbcTemplate;
//保存员工信息到数据库
public void save( Employee employee)
{
String sql="insert employee values(?,?,?,?,?)";
jdbcTemplate.update(sql,employee.getId(),employee.getName(),employee.getDepartment(),
employee.getEamil(),employee.getGender());
}
//查询并返回对应员工信息
public Employee exist(Employee employee)
{
String sql="select * from employee where name=? and id= ?";
try{
Employee employee1 = jdbcTemplate.queryForObject(sql, new BeanPropertyRowMapper<Employee>(Employee.class), employee.getName(), employee.getId());
return employee1;
}
catch (Exception e)
{
return null;
}
}
//删除某个员工的信息
public void delete(Employee employee)
{
String sql="delete from employee where id=?";
jdbcTemplate.update(sql,employee.getId());
}
//返回所有员工的信息
public List<Employee> getAllEmployees()
{
String sql="select* from employee";
List<Employee> list = jdbcTemplate.query(sql, new BeanPropertyRowMapper<Employee>(Employee.class));
return list;
}
}
POJO—自定义对象层
employee类:
代码语言:javascript复制@Component
public class Employee {
private Integer id;
private String name;
private String department;
private String eamil;
private Integer gender;
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getDepartment() {
return department;
}
public void setDepartment(String department) {
this.department = department;
}
public String getEamil() {
return eamil;
}
public void setEamil(String eamil) {
this.eamil = eamil;
}
public Integer getGender() {
return gender;
}
public void setGender(Integer gender) {
this.gender = gender;
}
@Override
public String toString() {
return "Employee{"
"id=" id
", name='" name '''
", department='" department '''
", eamil='" eamil '''
", gender=" gender
'}';
}
}
展示所有员工的界面设计思路
访问index.jsp---->直接发送/emps请求----->控制器查询所有员工-------->放在请求域中-------->转发到list页面进行展示
index.jsp:
代码语言:javascript复制<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%--访问页面就直接展示员工列表页面--%>
<jsp:forward page="/emps"></jsp:forward>
EmployeeController类:
代码语言:javascript复制@Controller
public class EmployeeController {
@Autowired
EmployeeDao employeeDao;
@RequestMapping("/emps")
public String getEmps(Model model)
{
List<Employee> all = employeeDao.getAllEmployees();
for(Employee employee:all)
System.out.println(employee);
System.out.println("当前方法调用一次");
model.addAttribute("employees",all);
return "list";
}
}
list.jsp:
代码语言:javascript复制<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<html>
<head>
<title>员工展示页面</title>
</head>
<body>
<%--cellpadding标签属性:设定单元边沿与单元内容之间的间距--%>
<%--cellspacing 标签属性:设定单元格之间的间距--%>
<table border="1px" cellpadding="5px" cellspacing="0" bgcolor="grey">
<%--
private Integer id;
private String name;
private String department;
private String eamil;
private String gender;--%>
<tr>
<th>员工ID</th>
<th>员工姓名</th>
<th>员工部门</th>
<th>员工邮箱</th>
<th>员工性别</th>
<td>修改</td>
<td>删除</td>
</tr>
<c:forEach items="${employees}" var="emp">
<tr>
<%-- 取出容器中的值--%>
<td>${emp.id}</td>
<td>${emp.name}</td>
<td>${emp.department}</td>
<td>${emp.eamil}</td>
<td>${emp.gender==0?"女":"男"}</td>
<td>修改</td>
<td>删除</td>
</tr>
</c:forEach>
</table>
</body>
</html>
添加员工
EmployeeController类新增方法:
代码语言:javascript复制 /*从数据库中查询出所有部门信息*/
@RequestMapping("/toAddPage")
public String toAddPage(Model model)
{
List<Employee> all = employeeDao.getAllEmployees();
List<String> departName = new LinkedList<String>();
for(Employee employee:all)
{
departName.add(employee.getDepartment());
}
model.addAttribute("departments",departName);
return "addPage";
}
addPage.jsp
代码语言:javascript复制<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<html>
<head>
<title>员工添加页面</title>
</head>
<body>
<h1 style="color: greenyellow">添加员工</h1>
<form action="">
员工id:<input name="id" placeholder="请输入员工id"><br/>
姓名: <input name="name" placeholder="请输入姓名"><br/>
邮箱: <input name="eamil" placeholder="请输入员工邮箱"><br/>
性别: 男<input type="radio" name="gender" value="1">
女<input type="radio" name="gender" value="0"><br/>
请选择员工所在部门:
<select name="department">
<c:forEach items="${departments}" var="dept">
<option value="${dept}">${dept}</option>
</c:forEach>
</select>
<input type="submit" value="提交">
</form>
</body>
</html>
Spring表单标签技术
需要在最上面导入Spring提供的标签库
代码语言:javascript复制<%@ taglib prefix="form" uri="http://www.springframework.org/tags/form" %>
好处
通过SpringMVC的表单标签可以实现将模型数据中的属性和HTML表单元素相绑定 以实现表单数据更便捷编辑和表单值的回显
spring标签库,替换上面的html写的form表单
代码语言:javascript复制<form:form>
<%--
path就是原来html----input标签里面的name项,即提交得到的key
path的作用:
1.当做原生的name项
2.自动回显隐含模型中某个对象对应的这个属性的值
--%>
员工id:<form:input path="id"/><br/>
姓名:<form:input path="name"/><br/>
邮箱:<form:input path="eamil"/><br/>
性别:<br/>
男:<form:radiobutton path="gender" value="1"/>
女:<form:radiobutton path="gender" value="0"/>
请选择员工所在的部门:
<%--items:指定要遍历的集合,自动遍历
如果遍历出来的是一个自定义对象
itemLabel="属性名": 指定遍历出来的这个对象的哪个属性是作为optiob标签体的值--->在页面显示要选择的选项里面显示的内容
itemValue="属性名":指定刚才遍历出来的这个对象的哪个属性是作为要提交的value值--%>
<form:select path="department" items="${departments}"/>
<br/>
<%--原生的html标签和spring标签混合使用--%>
<input type="submit" value="提交">
</form:form>
注意:SpringMVC认为,表单数据中的每一项最终都是要回显的
path指定的是一个属性,这个属性是从隐含模型(请求域)中取出的某个对象中的属性
path指定的每一个属性,请求域中必须有一个对象,拥有这个属性
这个对象就是请求域中的command的值,没有就报错,错误如下:
在隐含模型中放入command对象
EmployeeController类:
代码语言:javascript复制 /*从数据库中查询出所有部门信息*/
@RequestMapping("/toAddPage")
public String toAddPage(Model model)
{
List<Employee> all = employeeDao.getAllEmployees();
List<String> departName = new LinkedList<String>();
for(Employee employee:all)
{
departName.add(employee.getDepartment());
}
model.addAttribute("departments",departName);
/*在隐含模型中放入一个command对象*/
model.addAttribute("command",new Employee());
return "addPage";
}
addPages.jsp:
代码语言:javascript复制<form:form>
<%--
path就是原来html----input标签里面的name项,即提交得到的key
path的作用:
1.当做原生的name项
2.自动回显隐含模型中某个对象对应的这个属性的值
--%>
员工id:<form:input path="id"/><br/>
姓名:<form:input path="name"/><br/>
邮箱:<form:input path="eamil"/><br/>
性别:<br/>
男:<form:radiobutton path="gender" value="1"/>
女:<form:radiobutton path="gender" value="0"/>
请选择员工所在的部门:
<%--items:指定要遍历的集合,自动遍历
如果遍历出来的是一个自定义对象
itemLabel="属性名": 指定遍历出来的这个对象的哪个属性是作为optiob标签体的值--->在页面显示要选择的选项里面显示的内容
itemValue="属性名":指定刚才遍历出来的这个对象的哪个属性是作为要提交的value值--%>
<form:select path="department" items="${departments}"/>
<br/>
<%--原生的html标签和spring标签混合使用--%>
<input type="submit" value="提交">
</form:form>
以前我们表单标签会从请求域中获取一个command对象,把这个对象中每一个属性对应的显示在页面上
可以告诉SpringMVC不要去取command的值了,我放了一个modelAttribute指定的值,取对象用的key就使用我modelAttribute指定的
演示:
EmployeeController类:
代码语言:javascript复制 /*从数据库中查询出所有部门信息*/
@RequestMapping("/toAddPage")
public String toAddPage(Model model)
{
List<Employee> all = employeeDao.getAllEmployees();
List<String> departName = new LinkedList<String>();
for(Employee employee:all)
{
departName.add(employee.getDepartment());
}
model.addAttribute("departments",departName);
/*在隐含模型中放入一个employee对象*/
model.addAttribute("employee",new Employee(null,"超级大忽悠","空军部","@307667",1));
return "addPage";
}
addPage.jsp
代码语言:javascript复制<form:form modelAttribute="employee">
<%--
path就是原来html----input标签里面的name项,即提交得到的key
path的作用:
1.当做原生的name项
2.自动回显隐含模型中某个对象对应的这个属性的值
--%>
员工id:<form:input path="id"/><br/>
姓名:<form:input path="name"/><br/>
邮箱:<form:input path="eamil"/><br/>
性别:<br/>
男:<form:radiobutton path="gender" value="1"/>
女:<form:radiobutton path="gender" value="0"/>
请选择员工所在的部门:
<%--items:指定要遍历的集合,自动遍历
如果遍历出来的是一个自定义对象
itemLabel="属性名": 指定遍历出来的这个对象的哪个属性是作为optiob标签体的值--->在页面显示要选择的选项里面显示的内容
itemValue="属性名":指定刚才遍历出来的这个对象的哪个属性是作为要提交的value值--%>
<form:select path="department" items="${departments}"/>
<br/>
<%--原生的html标签和spring标签混合使用--%>
<input type="submit" value="提交">
</form:form>
点击提交按钮,对数据进行保存
以后jsp页面什么form表单的action提交路径,a标签的herf属性都写绝对路径,因此需要先获取项目根路径
代码语言:javascript复制//将当前项目的根路径存储再pageContext域中
<%pageContext.setAttribute("ctp",request.getContextPath());%>
<form:form modelAttribute="employee" action="${ctp}/emp" method="post">
处理表单提交请求的方法
代码语言:javascript复制 //只接收Post请求
@RequestMapping(value = "/emp",method = RequestMethod.POST)
public String addEmp(Employee employee)//这里会自动赋值
{
System.out.println("要添加的员工信息:" employee);
employeeDao.save(employee);
//返回列表页面,直接重定向到查询所有员工的请求
return "redirect:/emps";
}
修改员工
注意:被@ModelAttribute注解的方法会在所有的controller方法执行之前执行,即每一个controller方法执行之前,都会执行该方法
被@ModelAttribute注解的方法和目标controller方法用的都是一套的resolve方法,因此目标方法里面能写什么,获取什么,注解方法里面也能写和获取对应的内容
在EmployeeDao类中新增一个按照id查找对应员工的方法:
代码语言:javascript复制 //按照员工的id查找对应的员工
public Employee getEmpById(Integer id)
{
String sql="select * from employee where id= ?";
try{
Employee employee1 = jdbcTemplate.queryForObject(sql, new BeanPropertyRowMapper<Employee>(Employee.class),id);
return employee1;
}
catch (Exception e)
{
return null;
}
}
EmployeeController类:按照id查询对应的员工
代码语言:javascript复制 @RequestMapping("/emp/{id}")
public String getEmp(@PathVariable("id")Integer id,Model model)
{
//1.按照对应id去数据库中查出对应的员工信息
Employee emp = employeeDao.getEmpById(id);
//2.放在隐含模型中
model.addAttribute("EditEmp",emp);
//3.全部的部门信息放到隐含模型中,是为了可以在下拉框中修改部门信息
List<Employee> all = employeeDao.getAllEmployees();
List<String> departName = new LinkedList<String>();
for(Employee employee:all)
{
departName.add(employee.getDepartment());
}
model.addAttribute("departments",departName);
return "edit";
}
UpdateEmp方法:修改员工的方法,只有put请求才会接收
modelAttributes方法:取出数据库中的对应对象,在该对象的基础上进行修改,而不是新建一个对象
代码语言:javascript复制 /*虽然上面也有/emp/{id}的请求路径方式,但是没有限制请求方式,而下面我们限制了请求方式
优先精确匹配*/
/*修改员工的方法,只有put请求才会接收*/
@RequestMapping(value = "/emp/{id}",method = RequestMethod.PUT)
//在从数据库取出来的对象数据的基础上进行修改
public String UpdateEmp(@ModelAttribute("employee") Employee employee)
{
System.out.println("要修改的员工:" employee);
//调用数据库中修改对象数据的方法,员工的id是不变的
employeeDao.UpdateEmp(employee);
return "redirect:/emps";
}
@ModelAttribute
/*从请求参数中拿到id*/
public void modelAttributes(@RequestParam(value = "id",required = false)Integer id,Model model)
{
if(id!=null)
{
Employee emp = employeeDao.getEmpById(id);
model.addAttribute("employee",emp);
}
System.out.println("提前运行的方法调用了");
}
edit.jsp
代码语言:javascript复制<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%@ taglib prefix="form" uri="http://www.springframework.org/tags/form" %>
<html>
<head>
<title>员工修改页面</title>
</head>
<h1 style="color: hotpink">员工信息修改</h1>
<% pageContext.setAttribute("ctp",request.getContextPath());%>
<body>
<%--modelAttribute:这个表单的所有内容显示绑定的是请求域中EditEmp的值--%>
<form:form action="${ctp}/emp/${EditEmp.id}"
modelAttribute="EditEmp"
method="post">
<%--put---->对应Rest风格的更新请求,这里hiiden是为了不在页面上显示处理,隐藏数据--%>
<input type="hidden" name="_method" value="put">
<%--员工id不能修改,可以采用隐藏数据的模式,但是不安全--%>
<input type="hidden" name="id" value="${EditEmp.id}">
姓名:<form:input path="name"/><br/>
邮箱:<form:input path="eamil"/><br/>
性别:<br/>
男:<form:radiobutton path="gender" value="1"/>
女:<form:radiobutton path="gender" value="0"/>
请选择员工所在的部门:
<form:select path="department" items="${departments}"/>
<br/>
<input type="submit" value="修改">
</form:form>
</body>
</html>
这里逻辑有一个小bug,部门的种类应该单独创建一个类,而不是按照扫描当前数据库所有员工获取所有的部门种类,这里懒的改了
删除功能实现
list.jsp:
代码语言:javascript复制<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<html>
<head>
<title>员工展示页面</title>
</head>
<% pageContext.setAttribute("ctp",request.getContextPath());%>
<body>
<%--cellpadding标签属性:设定单元边沿与单元内容之间的间距--%>
<%--cellspacing 标签属性:设定单元格之间的间距--%>
<table border="1px" cellpadding="5px" cellspacing="0" bgcolor="grey">
<tr>
<th>员工ID</th>
<th>员工姓名</th>
<th>员工部门</th>
<th>员工邮箱</th>
<th>员工性别</th>
<td>修改</td>
<td>删除</td>
</tr>
<c:forEach items="${employees}" var="emp">
<tr>
<%-- 取出容器中的值--%>
<td>${emp.id}</td>
<td>${emp.name}</td>
<td>${emp.department}</td>
<td>${emp.eamil}</td>
<td>${emp.gender==0?"女":"男"}</td>
<td><a href="${ctp}/emp/${emp.id}">修改</a></td>
<td>
<form action="${ctp}/emp/${emp.id}" method="post">
<input type="hidden" name="_method" value="delete"/>
<input type="submit" value="删除"/>
</form>
</td>
</tr>
</c:forEach>
</table>
<a href="toAddPage" >添加员工</a>
</body>
</html>
deleteEmp方法:负责删除员工
代码语言:javascript复制 //删除方法
@RequestMapping(value = "/emp/{id}",method = RequestMethod.DELETE)
public String deleteEmp(@PathVariable("id") Integer id)
{
employeeDao.delete(id);
return "redirect:/emps";
}
最终完整源码呈现
目录结构
web.xml
代码语言:javascript复制<?xml version="1.0" encoding="UTF-8"?>
<web-app version="2.4"
xmlns="http://java.sun.com/xml/ns/j2ee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd">
<!--配置springmcv的前段控制器-->
<servlet>
<servlet-name>DispatcherServlet</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<!--SpringMvc.xml是前段控制器需要使用-->
<!--sevlet的初始化参数-->
<!--contextConfigLocation:指定SpringMVC配置文件的位置-->
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:SpringMVC.xml</param-value>
</init-param>
<!--默认第一次访问时创建对象,这里填入1,表示服务器启动时创建镀锡-->
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>DispatcherServlet</servlet-name>
<!--
/和/*都是拦截所有请求,但是/*的范围更大,还会拦截到*.jsp这些请求
一旦拦截jsp页面就不会显示了
/会拦截所有请求,但是不会拦截*.jsp,能保证jsp访问正常
-->
<url-pattern>/</url-pattern>
</servlet-mapping>
<!--配置一个字符编码的Filter-->
<filter>
<filter-name>CharacterEncodingFilter</filter-name>
<filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>
<!--初始化参数-->
<!--encoding:指定解决POST请求的乱码-->
<init-param>
<param-name>encoding</param-name>
<param-value>UTF-8</param-value>
</init-param>
<!--forceEncoding:顺手解决响应乱码
response.setCharacterEncoding(this.encoding)-->
<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>
<!--支持REST风格的filter-->
<!--配置filter-->
<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>
index.jsp
代码语言:javascript复制<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%--访问页面就直接展示员工列表页面--%>
<jsp:forward page="/emps"></jsp:forward>
addPages.jsp
代码语言:javascript复制<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<%@ taglib prefix="form" uri="http://www.springframework.org/tags/form" %>
<html>
<head>
<title>员工添加页面</title>
</head>
<body>
<%pageContext.setAttribute("ctp",request.getContextPath());%>
<form:form modelAttribute="employee" action="${ctp}/emp" method="post">
<%--
path就是原来html----input标签里面的name项,即提交得到的key
path的作用:
1.当做原生的name项
2.自动回显隐含模型中某个对象对应的这个属性的值
--%>
员工id:<form:input path="id"/><br/>
姓名:<form:input path="name"/><br/>
邮箱:<form:input path="eamil"/><br/>
性别:<br/>
男:<form:radiobutton path="gender" value="1"/>
女:<form:radiobutton path="gender" value="0"/>
请选择员工所在的部门:
<%--items:指定要遍历的集合,自动遍历
如果遍历出来的是一个自定义对象
itemLabel="属性名": 指定遍历出来的这个对象的哪个属性是作为optiob标签体的值--->在页面显示要选择的选项里面显示的内容
itemValue="属性名":指定刚才遍历出来的这个对象的哪个属性是作为要提交的value值--%>
<form:select path="department" items="${departments}"/>
<br/>
<input type="submit" value="提交">
</form:form>
<%--原生的html标签和spring标签混合使用--%>
<%--<h1 style="color: greenyellow">添加员工</h1>
<form action="">
员工id:<input name="id" placeholder="请输入员工id"><br/>
姓名: <input name="name" placeholder="请输入姓名"><br/>
邮箱: <input name="eamil" placeholder="请输入员工邮箱"><br/>
性别: 男<input type="radio" name="gender" value="1">
女<input type="radio" name="gender" value="0"><br/>
请选择员工所在部门:
<select name="department">
<c:forEach items="${departments}" var="dept">
<option value="${dept}">${dept}</option>
</c:forEach>
</select>
<input type="submit" value="提交">
</form>--%>
</body>
</html>
add.jsp
代码语言:javascript复制<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%@ taglib prefix="form" uri="http://www.springframework.org/tags/form" %>
<html>
<head>
<title>员工修改页面</title>
</head>
<h1 style="color: hotpink">员工信息修改</h1>
<% pageContext.setAttribute("ctp",request.getContextPath());%>
<body>
<%--modelAttribute:这个表单的所有内容显示绑定的是请求域中EditEmp的值--%>
<form:form action="${ctp}/emp/${EditEmp.id}"
modelAttribute="EditEmp"
method="post">
<%--put---->对应Rest风格的更新请求,这里hiiden是为了不在页面上显示处理,隐藏数据--%>
<input type="hidden" name="_method" value="put">
<%--员工id不能修改,可以采用隐藏数据的模式,但是不安全--%>
<input type="hidden" name="id" value="${EditEmp.id}">
姓名:<form:input path="name"/><br/>
邮箱:<form:input path="eamil"/><br/>
性别:<br/>
男:<form:radiobutton path="gender" value="1"/>
女:<form:radiobutton path="gender" value="0"/>
请选择员工所在的部门:
<form:select path="department" items="${departments}"/>
<br/>
<input type="submit" value="修改">
</form:form>
</body>
</html>
list.jsp
代码语言:javascript复制<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<html>
<head>
<title>员工展示页面</title>
</head>
<% pageContext.setAttribute("ctp",request.getContextPath());%>
<body>
<%--cellpadding标签属性:设定单元边沿与单元内容之间的间距--%>
<%--cellspacing 标签属性:设定单元格之间的间距--%>
<table border="1px" cellpadding="5px" cellspacing="0" bgcolor="grey">
<tr>
<th>员工ID</th>
<th>员工姓名</th>
<th>员工部门</th>
<th>员工邮箱</th>
<th>员工性别</th>
<td>修改</td>
<td>删除</td>
</tr>
<c:forEach items="${employees}" var="emp">
<tr>
<%-- 取出容器中的值--%>
<td>${emp.id}</td>
<td>${emp.name}</td>
<td>${emp.department}</td>
<td>${emp.eamil}</td>
<td>${emp.gender==0?"女":"男"}</td>
<td><a href="${ctp}/emp/${emp.id}">修改</a></td>
<td>
<form action="${ctp}/emp/${emp.id}" method="post">
<input type="hidden" name="_method" value="delete"/>
<input type="submit" value="删除"/>
</form>
</td>
</tr>
</c:forEach>
</table>
<a href="toAddPage" >添加员工</a>
</body>
</html>
jdbc.properties
代码语言:javascript复制jdbc.driver=com.mysql.jdbc.Driver
jdbc.url=jdbc:mysql://localhost:3306/tx
jdbc.username=root
jdbc.password=xxxxx
SpringMVC.xml
代码语言:javascript复制<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:mvc="http://www.springframework.org/schema/mvc"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
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
http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc.xsd">
<mvc:annotation-driven />
<!--context的组件扫描,需要引入context命名空间-->
<!--只需要扫描cotroller包下的内容-->
<context:component-scan base-package="com"/>
<!--加载jdbc.properties-->
<!--引入context命名空间-->
<context:property-placeholder location="classpath:jdbc.properties"/>
<!--数据源对象-->
<bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource">
<property name="driverClass" value="${jdbc.driver}"/>
<property name="jdbcUrl" value="${jdbc.url}"/>
<property name="user" value="${jdbc.username}"/>
<property name="password" value="${jdbc.password}"/>
</bean>
<!--jdbc模板对象-->
<bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate">
<property name="dataSource" ref="dataSource"/>
</bean>
<!--视图解析器-->
<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="prefix" value="/WEB-INF/pages/"/>
<property name="suffix" value=".jsp"/>
<!--指定创建jstlView-->
<!-- <property name="viewClass" value="org.springframework.web.servlet.view.JstlView"/>-->
</bean>
</beans>
EmployeeController
代码语言:javascript复制package com.Controller;
import com.Dao.EmployeeDao;
import com.POJO.Employee;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.*;
import java.util.LinkedList;
import java.util.List;
@Controller
public class EmployeeController {
@Autowired
EmployeeDao employeeDao;
/*从数据库中查询出所有员工信息*/
@RequestMapping("/emps")
public String getEmps(Model model)
{
List<Employee> all = employeeDao.getAllEmployees();
model.addAttribute("employees",all);
System.out.println("得到所有的员工");
return "list";
}
/*从数据库中查询出所有部门信息*/
@RequestMapping("/toAddPage")
public String toAddPage(Model model)
{
List<Employee> all = employeeDao.getAllEmployees();
List<String> departName = new LinkedList<String>();
for(Employee employee:all)
{
departName.add(employee.getDepartment());
}
model.addAttribute("departments",departName);
/*在隐含模型中放入一个employee对象*/
model.addAttribute("employee",new Employee(null,"超级大忽悠","空军部","@307667",1));
return "addPage";
}
//只接收Post请求
@RequestMapping(value = "/emp",method = RequestMethod.POST)
public String addEmp(Employee employee)//这里会自动赋值
{
System.out.println("要添加的员工信息:" employee);
employeeDao.save(employee);
//返回列表页面,直接重定向到查询所有员工的请求
return "redirect:/emps";
}
@RequestMapping("/emp/{id}")
public String getEmp(@PathVariable("id")Integer id,Model model)
{
//1.按照对应id去数据库中查出对应的员工信息
Employee emp = employeeDao.getEmpById(id);
//2.放在隐含模型中
model.addAttribute("EditEmp",emp);
//3.全部的部门信息放到隐含模型中
List<Employee> all = employeeDao.getAllEmployees();
List<String> departName = new LinkedList<String>();
for(Employee employee:all)
{
departName.add(employee.getDepartment());
}
model.addAttribute("departments",departName);
return "edit";
}
/*虽然上面也有/emp/{id}的请求路径方式,但是没有限制请求方式,而下面我们限制了请求方式
优先精确匹配*/
/*修改员工的方法,只有put请求才会接收*/
@RequestMapping(value = "/emp/{id}",method = RequestMethod.PUT)
//在从数据库取出来的对象数据的基础上进行修改
public String UpdateEmp(@ModelAttribute("employee") Employee employee)
{
System.out.println("要修改的员工:" employee);
//调用数据库中修改对象数据的方法,员工的id是不变的
employeeDao.UpdateEmp(employee);
return "redirect:/emps";
}
@ModelAttribute
/*从请求参数中拿到id*/
public void modelAttributes(@RequestParam(value = "id",required = false)Integer id,Model model)
{
if(id!=null)
{
Employee emp = employeeDao.getEmpById(id);
model.addAttribute("employee",emp);
}
System.out.println("提前运行的方法调用了");
}
//删除方法
@RequestMapping(value = "/emp/{id}",method = RequestMethod.DELETE)
public String deleteEmp(@PathVariable("id") Integer id)
{
employeeDao.delete(id);
return "redirect:/emps";
}
}
EmployeeDao
代码语言:javascript复制package com.Dao;
import com.POJO.Employee;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jdbc.core.BeanPropertyRowMapper;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.stereotype.Controller;
import org.springframework.stereotype.Repository;
import java.util.List;
import java.util.Map;
@Repository
public class EmployeeDao {
@Autowired //按照类型注入
JdbcTemplate jdbcTemplate;
//保存员工信息到数据库
public void save( Employee employee)
{
String sql="insert employee values(?,?,?,?,?)";
jdbcTemplate.update(sql,employee.getId(),employee.getName(),employee.getDepartment(),
employee.getEamil(),employee.getGender());
}
//查询并返回对应员工信息
public Employee exist(Employee employee)
{
String sql="select * from employee where name=? and id= ?";
try{
Employee employee1 = jdbcTemplate.queryForObject(sql, new BeanPropertyRowMapper<Employee>(Employee.class), employee.getName(), employee.getId());
return employee1;
}
catch (Exception e)
{
return null;
}
}
//删除某个员工的信息
public void delete(Integer id)
{
String sql="delete from employee where id=?";
jdbcTemplate.update(sql,id);
}
//返回所有员工的信息
public List<Employee> getAllEmployees()
{
String sql="select* from employee";
List<Employee> list = jdbcTemplate.query(sql, new BeanPropertyRowMapper<Employee>(Employee.class));
return list;
}
//按照员工的id查找对应的员工
public Employee getEmpById(Integer id)
{
String sql="select * from employee where id= ?";
try{
Employee employee1 = jdbcTemplate.queryForObject(sql, new BeanPropertyRowMapper<Employee>(Employee.class),id);
return employee1;
}
catch (Exception e)
{
return null;
}
}
//修改员工的信息
public void UpdateEmp(Employee employee)
{
//对员工进行进行修改
String sql="update employee set name=? ,department=? ,eamil=? ,gender=? where id=?";
jdbcTemplate.update(sql,employee.getName(),employee.getDepartment(),employee.getEamil(),employee.getGender()
,employee.getId());
}
}
Employee
代码语言:javascript复制package com.POJO;
import org.springframework.stereotype.Component;
@Component
public class Employee {
private Integer id;
private String name;
private String department;
private String eamil;
private Integer gender;
public Employee(Integer id, String name, String department, String eamil, Integer gender) {
this.id = id;
this.name = name;
this.department = department;
this.eamil = eamil;
this.gender = gender;
}
public Employee() {
}
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getDepartment() {
return department;
}
public void setDepartment(String department) {
this.department = department;
}
public String getEamil() {
return eamil;
}
public void setEamil(String eamil) {
this.eamil = eamil;
}
public Integer getGender() {
return gender;
}
public void setGender(Integer gender) {
this.gender = gender;
}
@Override
public String toString() {
return "Employee{"
"id=" id
", name='" name '''
", department='" department '''
", eamil='" eamil '''
", gender=" gender
'}';
}
}