本文承接《Web 项目 tiger 之7 添加用户》
需求分析
- 用户添加完成之后,现在开始做编辑功能,基本和以前传统的区别不大,学习亮点仍然在于前端 Html 页面中的 Thymeleaf 写法
UserDaoImpl
package com.lct.dao;
import com.lct.domain.Department;
import com.lct.domain.User;
import org.springframework.stereotype.Repository;
import org.thymeleaf.util.StringUtils;
import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.List;
@Repository
public class UserDaoImpl {
@Resource
private DepartmentDaoImpl departmentDao;
/**
* 默认的用户列表数据,暂时就不通过数据库了,直接初始化一些数据进行模拟
*/
private static List<User> userList = null;
static {
userList = new ArrayList<>();
userList.add(new User(1001, "E-AA", "[email protected]", 1, new Department(101, "系统部")));
userList.add(new User(1002, "E-BB", "[email protected]", 1, new Department(102, "研发部")));
userList.add(new User(1003, "E-CC", "[email protected]", 0, new Department(103, "采购部")));
userList.add(new User(1004, "E-DD", "[email protected]", 0, new Department(104, "财务部")));
userList.add(new User(1005, "E-EE", "[email protected]", 1, new Department(105, "后勤部")));
}
/**
* 模拟查询所有员工
*/
public List<User> getAll() {
return userList;
}
/**
* 根据id 查找用户
*
* @param id
* @return
*/
public User getUserById(Integer id) {
for (User user : userList) {
System.out.println(user.getUId() + " PPPPP " + id);
if (user.getUId().equals(id)) {
return user;
}
}
return null;
}
/**
* 添加用户
*
* @param user
*/
public void saveUser(User user) {
if (user == null) {
return;
}
/**
* 动态修改主键id
*/
user.setUId(userList.get(userList.size() - 1).getUId() + 1);
/**
* 因为页面传入的 Department 只有depId,所以根据id查询它整个实体回来
*/
user.setDepartment(departmentDao.getDepartmentById(user.getDepartment().getDepId()));
userList.add(user);
}
/**
* 修改用户
*
* @param user
*/
public void updateUser(User user) {
if (user != null) {
/** 因为页面提交的用户管理的部门数据只有部门id,所以要二次查询*/
user.setDepartment(departmentDao.getDepartmentById(user.getDepartment().getDepId()));
for (int i = 0; i < userList.size(); i++) {
if (userList.get(i).getUId().equals(user.getUId())) {
userList.set(i, user);
break;
}
}
}
}
}
UserController
package com.lct.controller;
import com.lct.dao.DepartmentDaoImpl;
import com.lct.dao.UserDaoImpl;
import com.lct.domain.Department;
import com.lct.domain.User;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.*;
import javax.annotation.Resource;
import javax.servlet.http.HttpSession;
import java.util.List;
/**
* Created by Administrator on 2018/7/28 0028.
* 用户控制器层
*/
@Controller
@RequestMapping("user")
public class UserController {
@Resource
private UserDaoImpl userDao;
@Resource
private DepartmentDaoImpl departmentDao;
/**
* 用户登录
*
* @param username 账号
* @param password 密码
* @param httpSession 设值登录的 用户session
* @return 登录成功 重定向到 用户列表页面
* @PostMapping ("login") 相当于 @RequestMapping(value = "login",method = RequestMethod.POST) 的简写
* 同理还有 @GetMapping 、@PutMapping 、@DeleteMapping
*/
@PostMapping("login")
public String login(String username, String password, HttpSession httpSession) {
/**
* 当账号不为空,密码为 123456 时,模拟登录成功,否则失败时重定向返回登录页面
*/
if (!StringUtils.isEmpty(username) && "123456".equals(password)) {
httpSession.setAttribute("userName", username);
return "redirect:/user/users";
} else {
/** 往服务器重定向时 要以 "/" 开头表示应用根地址*/
return "redirect:/index";
}
}
/**
* 页面点击 "商品销量" 链接时 进入,然后跳转到 products.html 页面
*
* @return
*/
@GetMapping("products")
public String priduct() {
return "products";
}
/**
* 跳转到用户列表页面
*
* @param model 用户设值返回页面
* @return
*/
@GetMapping("users")
public String findAllUsers(Model model) {
List<User> userList = userDao.getAll();
model.addAttribute("userList", userList);
/** 往前端 Thymeleaf 模板引擎时,开头不要加 "/" ,因为它默认配置就是:
* 前缀:spring.thymeleaf.prefix=classpath:/templates/
* 后缀:spring.thymeleaf.suffix=.html */
return "userList";
}
/**
* 用户添加前页面跳转-----用户点击"用户添加"按钮时,进入此处进行跳转到添加页面
*
* @param model
* @return
*/
@GetMapping(value = "userCRUD")
public String toAddUser(Model model) {
/**
* 因为用户添加页面上,需要选择用户属于哪个部门,所以要将部门数据全部带出去
*/
List<Department> departmentList = departmentDao.getDepartments();
model.addAttribute("departmentList", departmentList);
return "userAdd";
}
/**
* 用户添加-----用户添加提交时进入
* <p/>
* SpringMVC 自动将请求参数和入参对象的属性进行一一映射绑定
* 要求是请求参数的名字和 User 的属性名一样
*
* @param user
* @return
*/
@PostMapping(value = "userCRUD")
public String addUser(User user) {
/**
* 保存数据
*/
userDao.saveUser(user);
/** redirect: 表示重定向到一个后台地址 " /" 代表当前项目路径
* forward: 表示转发到一个后台地址
* 两者都是get请求方式
*/
return "redirect:/user/users";
}
/**
* 用户编辑前页面跳转-----用户点击"编辑"按钮时,进入此处进行跳转到编辑页面
* 因为编辑与添加页面一致,所以采用同一个页面,当然可以复制一份新的
*
* @param userId :待修改的用户id
* @param model
* @return
*/
@GetMapping(value = "userCRUD/{userId}")
public String toEditUser(@PathVariable(value = "userId") Integer userId, Model model) {
/**
* 查询出用户数据已经所有部门数据返回
*/
User user = userDao.getUserById(userId);
List<Department> departmentList = departmentDao.getDepartments();
model.addAttribute("departmentList", departmentList);
model.addAttribute("user", user);
/**
* 因为编辑与添加,布局标签是一样的,所以仍然跳转到添加页面
*/
/** 往前端 Thymeleaf 模板引擎时,开头不要加 "/" ,因为它默认配置就是:
* 前缀:spring.thymeleaf.prefix=classpath:/templates/
* 后缀:spring.thymeleaf.suffix=.html */
return "userAdd";
}
/**
* 用户修改-----用户修改提交时进入
* <p/>
* SpringMVC 自动将请求参数和入参对象的属性进行一一映射绑定
* 要求是请求参数的名字和 User 的属性名一样
*
* @param user
* @return
*/
@PutMapping(value = "userCRUD")
public String updateUser(User user) {
/**
* 修改数据
*/
userDao.updateUser(user);
/** redirect: 表示重定向到一个后台地址 " /" 代表当前项目路径
* forward: 表示转发到一个后台地址
* 两者都是get请求方式
* 修改之后仍然跳转到查询所有用户页面
*/
return "redirect:/user/users";
}
}
userList. html
<td th:text="${user.department.depName}"></td>
<td>
<!-- 点击编辑按钮后,进入后台;路径中使用"+"号将两个运算符的结果连接起来-->
<a class="btn btn-sm btn-primary" th:href="@{/user/userCRUD/}+${user.uId}">编辑</a>
<button class="btn btn-sm btn-danger deleteBtn">删除</button>
</td>
</tr>
userAdd. html
- 这里是学习的重点
- 前台往后台发送 put 请求修改员工数据,form 表单的 method 属性值只有 get 与 post 两种,所以 form 表单使用 put 请求方式,步骤如下:
- SpringMVC 中配置 HiddenHttpMethodFilter;(Spring Boot 已自动配置好,不用再管)
- 页面创建一个 post 请求方式的表单
- post 请求方式表单中创建一个 input 项,name 属性值强制为 "_method",value 属性值就是指定此 form 请求的方式,即 put
<!DOCTYPE html>
<!-- saved from url=(0052)http://getbootstrap.com/docs/4.0/examples/dashboard/ -->
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
<meta name="description" content="">
<meta name="author" content="">
<title>Dashboard Template for Bootstrap</title>
<!-- Bootstrap core CSS -->
<link href="asserts/css/bootstrap.min.css" th:href="@{/webjars/bootstrap/4.0.0/css/bootstrap.css}" rel="stylesheet">
<!-- Custom styles for this template -->
<link href="asserts/css/dashboard.css" th:href="@{/asserts/css/dashboard.css}" rel="stylesheet">
<style type="text/css">
/* Chart.js */
@-webkit-keyframes chartjs-render-animation {
from {
opacity: 0.99
}
to {
opacity: 1
}
}
@keyframes chartjs-render-animation {
from {
opacity: 0.99
}
to {
opacity: 1
}
}
.chartjs-render-monitor {
-webkit-animation: chartjs-render-animation 0.001s;
animation: chartjs-render-animation 0.001s;
}
</style>
</head>
<body>
<!--在原来的位置引用公共的头部元素,原来的 <nav元素就是在这里的
commonsHead:模板名,根据Spring Boot配置的Thymeleaf映射查找
head:是模板中公用的代码片段-->
<div th:replace="commons::head"></div>
<div class="container-fluid">
<div class="row">
<!-- 在原来的左侧菜单位置引用抽取好的公共左侧菜单代码
1、这是使用的 id选择器 进行的引用
2、引用公共代码的片段的同时传递参数值过去-->
<div th:replace="commons::#commonsLeft(activeUri='userList')"></div>
<main role="main" class="col-md-9 ml-sm-auto col-lg-10 pt-3 px-4">
<!--提交后进入后台地址-->
<form method="post" th:action="@{/user/userCRUD}">
<!--发送put请求修改员工数据,form的method只有get与post两种,使用put方式,步骤如下:
1、SpringMVC 中配置 HiddenHttpMethodFilter;(SpringBoot 已自动配置好,不用管了)
2、页面创建一个post表单,上面已经建好
3、创建一个input项,name强制为 "_method",value的值就是指定此form请求的方式,如下所示为 put
-->
<!-- th:if:条件满足时生成标签,否则不生成标签
1、修改是要传递用户id过去的,所以做成隐藏域-->
<input type="hidden" name="_method" value="put" th:if="${user!=null}"/>
<input type="hidden" name="uId" th:if="${user!=null}" th:value="${user.uId}">
<div class="form-group">
<label>姓名</label>
<!-- 三元运算符,当user不等于null时,取User的name属性值-->
<input name="uName" type="text" class="form-control" placeholder="华安"
th:value="${user!=null}?${user.uName}">
</div>
<div class="form-group">
<label>邮箱</label>
<!-- 三元运算符,当user不等于null时,取User的email属性值-->
<input name="email" type="email" class="form-control" placeholder="[email protected]"
th:value="${user!=null}?${user.email}">
</div>
<div class="form-group">
<label>性别</label><br/>
<div class="form-check form-check-inline">
<!-- 三元运算符,当user不等于null时,取User的gender属性值与0和1进行比较,用于选中单选框-->
<input class="form-check-input" type="radio" name="gender" value="1"
th:checked="${user!=null}?${user.gender==1}">
<label class="form-check-label">男</label>
</div>
<div class="form-check form-check-inline">
<input class="form-check-input" type="radio" name="gender" value="0"
th:checked="${user!=null}?${user.gender==0}">
<label class="form-check-label">女</label>
</div>
</div>
<div class="form-group">
<label>所属部门</label>
<!--部门表所有部门,进行遍历显示,供用户选择
注意:select的 name="department.depId",Spring MVC 会自动封装关联类 Department的depId,但是depName为null-->
<select class="form-control" name="department.depId">
<!-- 当user不等于null时,取User的Department的depId属性值与当前部门id进行比较,用于选中下拉框-->
<option th:each="department:${departmentList}"
th:text="${department.depName}"
th:value="${department.depId}"
th:selected="${user!=null}?${user.department.depId==department.depId}">
</option>
</select>
</div>
<div class="form-group">
<label>生日</label>
<!-- 当user不等于null时,获取生日的日期进行格式化-->
<input name="birth" type="text" class="form-control" placeholder="1893/08/25"
th:value="${user!=null}?${#dates.format(user.birth, 'yyyy-MM-dd HH:mm')}">
</div>
<!-- 当user不等于null时,按钮为 "修改",否则为 "添加",因为只有修改时,后台才会传递 User 对象过来 -->
<button type="submit" class="btn btn-primary" th:text="${user!=null}?'修改':'添加'">添加</button>
</form>
</main>
</div>
</div>
<!-- Bootstrap core JavaScript
================================================== -->
<!-- Placed at the end of the document so the pages load faster -->
<script type="text/javascript" src="asserts/js/jquery-3.2.1.slim.min.js"
th:src="@{/webjars/jquery/3.3.1/jquery.js}"></script>
<script type="text/javascript" src="asserts/js/popper.min.js"
th:src="@{/webjars/popper.js/1.11.1/dist/popper.js}"></script>
<script type="text/javascript" src="asserts/js/bootstrap.min.js"
th:src="@{/webjars/bootstrap/4.0.0/js/bootstrap.js}"></script>
<!-- Icons -->
<script type="text/javascript" src="asserts/js/feather.min.js" th:src="@{/asserts/js/feather.min.js}"></script>
<script>
feather.replace()
</script>
</body>
</html>