员工管理系统
1、准备工作
1、新建一个springboot项目,取名springboot-02-web,同时添加web依赖
2、将静态资源,html文件放到resources下的templates中,css/img/js都放到resources的static目录下
3、添加thymeleaf和lombok的依赖,在pom.xml中添加
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-thymeleaf</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.18.22</version>
</dependency>
</dependencies>
4、在application.properties中配置项目路径,类似配置Tomcat启动时的路径:localhost:8080/json
server.servlet.context-path=/json
5、编写实体类pojo
Department
package com.jian.pojo;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
@Data
@AllArgsConstructor
@NoArgsConstructor
public class Department {
private Integer id;
private String departmentName;
}
Employee
package com.jian.pojo;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import java.util.Date;
@Data
@NoArgsConstructor
public class Employee {
private Integer id;
private String lastName;
private String email;
private Integer gender;
private Department department;
private Date birth;
public Employee(Integer id, String lastName, String email, Integer gender, Department department) {
this.id = id;
this.lastName = lastName;
this.email = email;
this.gender = gender;
this.department = department;
//设置默认日期
this.birth = new Date();
}
}
6、编写dao接口,模拟数据交互
DepartmentDao
package com.jian.dao;
import com.jian.pojo.Department;
import org.springframework.stereotype.Repository;
import java.util.Collection;
import java.util.HashMap;
import java.util.Map;
@Repository
public class DepartmentDao {
//模拟数据库中的数据
private static Map<Integer, Department> departments;
static {
departments = new HashMap<Integer, Department>();
departments.put(101, new Department(101, "魏国"));
departments.put(102, new Department(102, "蜀国"));
departments.put(103, new Department(103, "吴国"));
departments.put(104, new Department(104, "晋朝"));
departments.put(105, new Department(105, "汉朝"));
}
//获取所有部门
public Collection<Department> getDepartments() {
return departments.values();
}
//通过id获取部门
public Department getDepartmentById(Integer id) {
return departments.get(id);
}
}
EmployeeDao
package com.jian.dao;
import com.jian.pojo.Department;
import com.jian.pojo.Employee;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Repository;
import java.util.Collection;
import java.util.HashMap;
import java.util.Map;
@Repository
public class EmployeeDao {
@Autowired
private DepartmentDao departmentDao;
private static Map<Integer, Employee> employees;
static {
employees = new HashMap<Integer, Employee>();
employees.put(1001, new Employee(1001, "Json", "116@qq.com", 1, new Department(101, "魏国")));
employees.put(1002, new Employee(1002, "Lisa", "117@qq.com", 0, new Department(102, "蜀国")));
employees.put(1003, new Employee(1003, "Andy", "118@qq.com", 0, new Department(103, "吴国")));
employees.put(1004, new Employee(1004, "Bob", "119@qq.com", 1, new Department(104, "晋朝")));
employees.put(1005, new Employee(1005, "Jack", "120@qq.com", 1, new Department(105, "汉朝")));
}
//主键自增
private static Integer initId = 1006;
//新增一位员工
public void add(Employee employee) {
if (employee.getId() == null) {
employee.setId(initId++);
}
employee.setDepartment(departmentDao.getDepartmentById(employee.getDepartment().getId()));
employees.put(employee.getId(), employee);
}
//获取全部员工
public Collection<Employee> getAll() {
return employees.values();
}
//根据Id获取员工
public Employee getEmployeeById(Integer id) {
return employees.get(id);
}
//根据Id删除员工
public void delete(Integer id) {
employees.remove(id);
}
}
7、自定义MVC配置类MyMvcConfig,添加视图控制器映射
package com.jian.config;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.LocaleResolver;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.ViewControllerRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
//如果你想DIY一些定制化的功能,只要写这个组件,然后将它交给springboot,springboot就会帮我们自动转配
@Configuration
public class MyMvcConfig implements WebMvcConfigurer {
@Override
public void addViewControllers(ViewControllerRegistry registry) {
//localhost:8080/json/或localhost:8080/json/index.html都可以映射到index.html页
registry.addViewController("/").setViewName("index");
registry.addViewController("/index.html").setViewName("index");
registry.addViewController("/main.html").setViewName("dashboard");
}
}
到这里准备工作就完成了,接下来就是具体业务代码编写咯
2、登录功能
1、修改登录页面index.html,其中所有涉及链接的一律改成@{…/…},例如:<link th:href="@{/css/bootstrap.min.css}" rel="stylesheet">
<!DOCTYPE html>
<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>Signin Template for Bootstrap</title>
<!-- Bootstrap core CSS -->
<link th:href="@{/css/bootstrap.min.css}" rel="stylesheet">
<!-- Custom styles for this template -->
<link th:href="@{/css/signin.css}" rel="stylesheet">
</head>
<body class="text-center">
<form class="form-signin" th:action="@{/user/login}">
<img class="mb-4" th:src="@{img/bootstrap-solid.svg}" alt="" width="72" height="72">
<h1 class="h3 mb-3 font-weight-normal" th:text="#{login.tip}">Please sign in</h1>
<!--回传信息接收-->
<p th:if="${not #strings.isEmpty(msg)}" th:text="${msg}" style="color: red"></p>
<label class="sr-only">Username</label>
<input type="text" name="username" class="form-control" th:placeholder="#{login.username}" required="" autofocus="">
<label class="sr-only">Password</label>
<input type="password" name="password" class="form-control" th:placeholder="#{login.password}" required="">
<div class="checkbox mb-3">
<label>
<input type="checkbox" value="remember-me" th:text="#{login.remember}">
</label>
</div>
<button class="btn btn-lg btn-primary btn-block" type="submit" th:text="#{login.btn}">Sign in</button>
<p class="mt-5 mb-3 text-muted">© 2017-2018</p>
<a class="btn btn-sm" th:href="@{/index.html(l='zh_CN')}">中文</a>
<a class="btn btn-sm" th:href="@{/index.html(l='en_US')}">English</a>
</form>
</body>
</html>
2、编写控制器LoginController
package com.jian.controller;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.thymeleaf.util.StringUtils;
import javax.servlet.http.HttpSession;
@Controller
public class LoginController {
@RequestMapping("/user/login")
public String login(@RequestParam("username") String username,
@RequestParam("password") String password,
Model model,
HttpSession session) {
if (!StringUtils.isEmpty(username) && "123456".equals(password)) {
session.setAttribute("loginUser", username);
return "redirect:/main.html";
} else {
model.addAttribute("msg", "用户名或密码错误");
return "index";
}
}
}
3、启动测试登录功能OK
但是这里又有一个问题啦:未登录用户直接在地址栏输入:localhost:8080/json/main.html也可以进入后台
解决办法添加拦截器
1、在config包下新增一个类LoginInterceptor,实现HandlerInterceptor便是一个拦截器类
package com.jian.config;
import org.springframework.web.servlet.HandlerInterceptor;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
public class LoginInterceptor implements HandlerInterceptor {
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
Object loginUser = request.getSession().getAttribute("loginUser");
if (loginUser == null) {
request.setAttribute("msg", "没有权限,请先登录");
request.getRequestDispatcher("/index.html").forward(request, response);
return false;
} else {
return true;
}
}
}
2、在MyMvcConfig类中添加自定义的拦截器,重写addInterceptors方法
@Override
public void addInterceptors(InterceptorRegistry registry) {
registry.addInterceptor(new LoginInterceptor()).addPathPatterns("/**").
excludePathPatterns("/index.html", "/", "/user/login", "/" +
"/img/*", "/css/*", "/js/*");
}
3、启动测试,输入localhost:8080/json/main.html成功被拦截
页面国际化功能
页面国际化功能即多种语言切换,比如中英切换
1、在resources目录下新建一个目录i18n(international的简称)
2、在i18n目录下新建login.properties、login_zh_CN.properties、login_en_US.properties三个配置文件
3、login.properties、login_zh_CN.properties、login.en_US.properties分别对应一下内容
login.properties(默认)
login.btn=登录
login.username=用户名
login.password=密码
login.remember=记住我
login.tip=请登录
login_zh_CN.properties
login.btn=登录
login.username=用户名
login.password=密码
login.remember=记住我
login.tip=请登录
login_en_US.properties
login.btn=Sign in
login.username=Username
login.password=Password
login.remember=Remember me
login.tip=Please sign in
4、application.properties中配置国际化文件的真实位置
#国际化配置文件的真实位置
spring.messages.basename=i18n.login
5、前端页面展示index.html
<!DOCTYPE html>
<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>Signin Template for Bootstrap</title>
<!-- Bootstrap core CSS -->
<link th:href="@{/css/bootstrap.min.css}" rel="stylesheet">
<!-- Custom styles for this template -->
<link th:href="@{/css/signin.css}" rel="stylesheet">
</head>
<body class="text-center">
<form class="form-signin" th:action="@{/user/login}">
<img class="mb-4" th:src="@{img/bootstrap-solid.svg}" alt="" width="72" height="72">
<h1 class="h3 mb-3 font-weight-normal" th:text="#{login.tip}">Please sign in</h1>
<!--回传信息接收-->
<p th:if="${not #strings.isEmpty(msg)}" th:text="${msg}" style="color: red"></p>
<label class="sr-only">Username</label>
<input type="text" name="username" class="form-control" th:placeholder="#{login.username}" required="" autofocus="">
<label class="sr-only">Password</label>
<input type="password" name="password" class="form-control" th:placeholder="#{login.password}" required="">
<div class="checkbox mb-3">
<label>
<input type="checkbox" value="remember-me" th:text="#{login.remember}">
</label>
</div>
<button class="btn btn-lg btn-primary btn-block" type="submit" th:text="#{login.btn}">Sign in</button>
<p class="mt-5 mb-3 text-muted">© 2017-2018</p>
<a class="btn btn-sm" th:href="@{/index.html(l='zh_CN')}">中文</a>
<a class="btn btn-sm" th:href="@{/index.html(l='en_US')}">English</a>
</form>
</body>
</html>
页面内容全是中文的啦,对应login.properties,前端取值用**#{login.xxx}**
再完善一下,实现中英文切换
1、index.html页面中有两个链接
<a class="btn btn-sm" th:href="@{/index.html(l='zh_CN')}">中文</a>
<a class="btn btn-sm" th:href="@{/index.html(l='en_US')}">English</a>
2、然后在config目录下新建一个类MyLocaleResolver,实现LocaleResolver接口
package com.jian.config;
import org.springframework.web.servlet.LocaleResolver;
import org.thymeleaf.util.StringUtils;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.Locale;
public class MyLocaleResolver implements LocaleResolver {
@Override
public Locale resolveLocale(HttpServletRequest request) {
//获取请求中的参数
String language = request.getParameter("l");
//默认的Locale
Locale locale = Locale.getDefault();
//如果请求的参数携带了国际化的参数
if (!StringUtils.isEmpty(language)) {
String[] str = language.split("_");
//国家、地区
locale = new Locale(str[0], str[1]);
}
return locale;
}
@Override
public void setLocale(HttpServletRequest request, HttpServletResponse response, Locale locale) {
}
}
3、在MyMvcConfig类中注册MyLocaleResolver的bean
@Bean
public LocaleResolver localeResolver() {
return new MyLocaleResolver();
}
4、启动测试,中英文切换成功
3、前端页面公共部分抽取
在templates下新建文件夹:emp和commons
emp文件夹放增删改查相关页面,commons中放入增删改查公共部分:头部、侧边栏等
commons.html
使用:==th:fragment=“xxx”==抽取公共部分,并取名xxx
<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<nav class="navbar navbar-dark sticky-top bg-dark flex-md-nowrap p-0" th:fragment="topbar">
<a class="navbar-brand col-sm-3 col-md-2 mr-0" href="#">[[${session.loginUser}]]</a>
<input class="form-control form-control-dark w-100" type="text" placeholder="Search" aria-label="Search">
<ul class="navbar-nav px-3">
<li class="nav-item text-nowrap">
<a class="nav-link" th:href="@{/user/logout}">注销</a>
</li>
</ul>
</nav>
<nav class="col-md-2 d-none d-md-block bg-light sidebar" th:fragment="sidebar">
<div class="sidebar-sticky">
<ul class="nav flex-column">
<li class="nav-item">
<a th:class="${active=='dashboard.html'?'nav-link active':'nav-link'}" th:href="@{/index.html}">
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="feather feather-home">
<path d="M3 9l9-7 9 7v11a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2z"></path>
<polyline points="9 22 9 12 15 12 15 22"></polyline>
</svg>
首页 <span class="sr-only">(current)</span>
</a>
</li>
<li class="nav-item">
<a class="nav-link" href="http://getbootstrap.com/docs/4.0/examples/dashboard/#">
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="feather feather-file">
<path d="M13 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V9z"></path>
<polyline points="13 2 13 9 20 9"></polyline>
</svg>
Orders
</a>
</li>
<li class="nav-item">
<a class="nav-link" href="http://getbootstrap.com/docs/4.0/examples/dashboard/#">
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="feather feather-shopping-cart">
<circle cx="9" cy="21" r="1"></circle>
<circle cx="20" cy="21" r="1"></circle>
<path d="M1 1h4l2.68 13.39a2 2 0 0 0 2 1.61h9.72a2 2 0 0 0 2-1.61L23 6H6"></path>
</svg>
Products
</a>
</li>
<li class="nav-item">
<a th:class="${active=='list.html'?'nav-link active':'nav-link'}" th:href="@{/emps/all}">
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="feather feather-users">
<path d="M17 21v-2a4 4 0 0 0-4-4H5a4 4 0 0 0-4 4v2"></path>
<circle cx="9" cy="7" r="4"></circle>
<path d="M23 21v-2a4 4 0 0 0-3-3.87"></path>
<path d="M16 3.13a4 4 0 0 1 0 7.75"></path>
</svg>
员工管理
</a>
</li>
<li class="nav-item">
<a class="nav-link" href="http://getbootstrap.com/docs/4.0/examples/dashboard/#">
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="feather feather-bar-chart-2">
<line x1="18" y1="20" x2="18" y2="10"></line>
<line x1="12" y1="20" x2="12" y2="4"></line>
<line x1="6" y1="20" x2="6" y2="14"></line>
</svg>
Reports
</a>
</li>
<li class="nav-item">
<a class="nav-link" href="http://getbootstrap.com/docs/4.0/examples/dashboard/#">
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="feather feather-layers">
<polygon points="12 2 2 7 12 12 22 7 12 2"></polygon>
<polyline points="2 17 12 22 22 17"></polyline>
<polyline points="2 12 12 17 22 12"></polyline>
</svg>
Integrations
</a>
</li>
</ul>
<h6 class="sidebar-heading d-flex justify-content-between align-items-center px-3 mt-4 mb-1 text-muted">
<span>Saved reports</span>
<a class="d-flex align-items-center text-muted" href="http://getbootstrap.com/docs/4.0/examples/dashboard/#">
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="feather feather-plus-circle"><circle cx="12" cy="12" r="10"></circle><line x1="12" y1="8" x2="12" y2="16"></line><line x1="8" y1="12" x2="16" y2="12"></line></svg>
</a>
</h6>
<ul class="nav flex-column mb-2">
<li class="nav-item">
<a class="nav-link" href="http://getbootstrap.com/docs/4.0/examples/dashboard/#">
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="feather feather-file-text">
<path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z"></path>
<polyline points="14 2 14 8 20 8"></polyline>
<line x1="16" y1="13" x2="8" y2="13"></line>
<line x1="16" y1="17" x2="8" y2="17"></line>
<polyline points="10 9 9 9 8 9"></polyline>
</svg>
Current month
</a>
</li>
<li class="nav-item">
<a class="nav-link" href="http://getbootstrap.com/docs/4.0/examples/dashboard/#">
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="feather feather-file-text">
<path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z"></path>
<polyline points="14 2 14 8 20 8"></polyline>
<line x1="16" y1="13" x2="8" y2="13"></line>
<line x1="16" y1="17" x2="8" y2="17"></line>
<polyline points="10 9 9 9 8 9"></polyline>
</svg>
Last quarter
</a>
</li>
<li class="nav-item">
<a class="nav-link" href="http://getbootstrap.com/docs/4.0/examples/dashboard/#">
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="feather feather-file-text">
<path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z"></path>
<polyline points="14 2 14 8 20 8"></polyline>
<line x1="16" y1="13" x2="8" y2="13"></line>
<line x1="16" y1="17" x2="8" y2="17"></line>
<polyline points="10 9 9 9 8 9"></polyline>
</svg>
Social engagement
</a>
</li>
<li class="nav-item">
<a class="nav-link" href="http://getbootstrap.com/docs/4.0/examples/dashboard/#">
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="feather feather-file-text">
<path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z"></path>
<polyline points="14 2 14 8 20 8"></polyline>
<line x1="16" y1="13" x2="8" y2="13"></line>
<line x1="16" y1="17" x2="8" y2="17"></line>
<polyline points="10 9 9 9 8 9"></polyline>
</svg>
Year-end sale
</a>
</li>
</ul>
</div>
</nav>
</html>
增删改查页面要引用公共部分使用格式如下:
<div th:insert="~{commons/commons::topbar}"></div>
<!--还可以传递参数active是参数名,()里是值-->
<div th:insert="~{commons/commons::sidebar(active='list.html')}"></div>
<div th:replace="~{commons/commons::sidebar(active='dashboard.html')}"></div>
公共页可以获取此参数
<a th:class="${active=='list.html'?'nav-link active':'nav-link'}" th:href="@{/emps/all}">
4、所有员工信息展示
1、编写EmpController
package com.jian.controller;
import com.jian.dao.DepartmentDao;
import com.jian.dao.EmployeeDao;
import com.jian.pojo.Department;
import com.jian.pojo.Employee;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import java.util.Collection;
@Controller
public class EmpController {
@Autowired
private EmployeeDao employeeDao;
@Autowired
private DepartmentDao departmentDao;
@RequestMapping("/emps/all")
public String getAll(Model model) {
Collection<Employee> employees = employeeDao.getAll();
model.addAttribute("list", employees);
return "emp/list";
}
}
2、编写前端页list.html,放在resources/templates/emp文件夹下,页面只留下body核心部分,后面也是如此
<!DOCTYPE html>
<!-- saved from url=(0052)http://getbootstrap.com/docs/4.0/examples/dashboard/ -->
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<body>
<div th:insert="~{commons/commons::topbar}"></div>
<div class="container-fluid">
<div class="row">
<div th:insert="~{commons/commons::sidebar(active='list.html')}"></div>
<main role="main" class="col-md-9 ml-sm-auto col-lg-10 pt-3 px-4">
<h2>
员工列表
<a th:href="@{/emps/add}" class="btn btn-success">添加员工</a>
</h2>
<div class="table-responsive">
<table class="table table-striped table-sm">
<thead>
<tr>
<th>id</th>
<th>lastName</th>
<th>email</th>
<th>gender</th>
<th>department</th>
<th>birth</th>
<th>操作</th>
</tr>
</thead>
<tbody>
<tr th:each="emp:${list}">
<td th:text="${emp.id}"></td>
<td th:text="${emp.lastName}"></td>
<td th:text="${emp.email}"></td>
<td th:text="${emp.gender}==0?'女':'男'"></td>
<td th:text="${emp.department.getDepartmentName()}"></td>
<td th:text="${#dates.format(emp.birth,'yyyy-MM-dd HH:mm:ss')}"></td>
<td>
<a class="btn btn-primary" th:href="@{/emps/update/{id}(id=${emp.id})}">修改</a>
<a class="btn btn-danger" th:href="@{/emps/delete/{id}(id=${emp.id})}">删除</a>
</td>
</tr>
</tbody>
</table>
</div>
</main>
</div>
</div>
</body>
</html>
5、添加员工
1、往EmpController中添加一下两个方法,一个是get请求用于跳转到添加页面,另外一个是post请求,执行添加操作,完事后重定向list.html
@GetMapping("/emps/add")
public String toAdd(Model model) {
Collection<Department> departments = departmentDao.getDepartments();
model.addAttribute("departments", departments);
return "emp/add";
}
@PostMapping("/emps/add")
public String add(Employee employee) {
employeeDao.add(employee);
return "redirect:/emps/all";
}
2、编写add.html,也是放在resources/templates/emp目录下
<div th:insert="~{commons/commons::topbar}"></div>
<div class="container-fluid">
<div class="row">
<div th:insert="~{commons/commons::sidebar(active='list.html')}"></div>
<main role="main" class="col-md-9 ml-sm-auto col-lg-10 pt-3 px-4">
<h2>
添加员工
</h2>
<div class="table-responsive">
<form th:action="@{/emps/add}" method="post">
<div class="form-group">
<label>姓名</label>
<input type="text" class="form-control" name="lastName" placeholder="海绵宝宝">
</div>
<div class="form-group">
<label>邮箱</label>
<input type="email" class="form-control" name="email" placeholder="1176244270@qq.com">
</div>
<div class="form-group">
<label>性别</label><br>
<div class="form-check form-check-inline">
<input class="form-check-input" type="radio" name="gender" value="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">
<label class="form-check-label">女</label>
</div>
</div>
<div class="form-group">
<label>部门</label>
<select class="form-control" name="department.id">
<option th:each="dept:${departments}" th:text="${dept.departmentName}" th:value="${dept.id}"></option>
</select>
</div>
<div class="form-group">
<label>出生日期</label>
<input type="text" class="form-control" name="birth" placeholder="1999/11/11">
</div>
<button type="submit" class="btn btn-primary">添加</button>
</form>
</div>
</main>
</div>
</div>
6、修改员工
1、往EmpController中添加以下方法,一个是get请求用于跳转到修改页面,另外一个是post请求,执行修改操作,完事后重定向list.html
@GetMapping("/emps/update/{id}")
public String toUpdate(@PathVariable("id") Integer id, Model model) {
Employee employee = employeeDao.getEmployeeById(id);
model.addAttribute("employee", employee);
Collection<Department> departments = departmentDao.getDepartments();
model.addAttribute("departments", departments);
return "emp/update";
}
@PostMapping("/emps/update")
public String update(Employee employee) {
employeeDao.add(employee);
return "redirect:/emps/all";
}
2、编写update.html
<div th:insert="~{commons/commons::topbar}"></div>
<div class="container-fluid">
<div class="row">
<div th:insert="~{commons/commons::sidebar(active='list.html')}"></div>
<main role="main" class="col-md-9 ml-sm-auto col-lg-10 pt-3 px-4">
<h2>
修改员工
</h2>
<div class="table-responsive">
<form th:action="@{/emps/update}" method="post">
<input type="hidden" name="id" th:value="${employee.id}">
<div class="form-group">
<label>姓名</label>
<input type="text" class="form-control" name="lastName" th:value="${employee.lastName}" placeholder="海绵宝宝">
</div>
<div class="form-group">
<label>邮箱</label>
<input type="email" class="form-control" name="email" th:value="${employee.email}" placeholder="1176244270@qq.com">
</div>
<div class="form-group">
<label>性别</label><br>
<div class="form-check form-check-inline">
<input th:checked="${employee.gender==1}" class="form-check-input" type="radio" name="gender" value="1">
<label class="form-check-label">男</label>
</div>
<div class="form-check form-check-inline">
<input th:checked="${employee.gender==0}" class="form-check-input" type="radio" name="gender" value="0">
<label class="form-check-label">女</label>
</div>
</div>
<div class="form-group">
<label>部门</label>
<select class="form-control" name="department.id">
<option th:selected="${employee.department.id==dept.id}" th:each="dept:${departments}" th:text="${dept.departmentName}" th:value="${dept.id}"></option>
</select>
</div>
<div class="form-group">
<label>出生日期</label>
<input type="text" th:value="${#dates.format(employee.birth,'yyyy-MM-dd HH:mm:ss')}" class="form-control" name="birth" placeholder="1999/11/11">
</div>
<button type="submit" class="btn btn-primary">修改</button>
</form>
</div>
</main>
</div>
</div>
修改时日期格式问题:springmvc默认格式时yyyy/MM/dd,但是前端提格式是yyyy-MM-dd,所以解决这个问题就要在application.properties中添加
spring.mvc.format.date=yyyy-MM-dd HH:mm:ss
7、删除员工
直接往EmpController中添加以下方法
@RequestMapping("/emps/delete/{id}")
public String delete(@PathVariable("id") Integer id) {
employeeDao.delete(id);
return "redirect:/emps/all";
}
前端页面查看list.html,里面有删除按钮
8、注销功能
往LoginController中添加以下方法
@RequestMapping("/user/logout")
public String logout(HttpSession session) {
session.removeAttribute("loginUser");
return "redirect:/index.html";
}
前端页面查看commons.html,里面有注销按钮
9、404页面
1、在templates目录下添加一个error目录
2、把404.html放入error目录即可