员工管理系统
1. 首页配置
注意点:所有页面的静态资源都需要使用thymeleaf接管:@{}
<link th:href="@{/css/bootstrap.min.css}" rel="stylesheet">
2. 页面国际化
- 先编写两个国际化文件,将需要国际化的属性分别添加
-
在配置文件中配置一下
#我们的配置文件的真实位置 spring.messages.basename=i18n.login
-
在前端页面中,用th:和#{}添加到具体字段或者按钮上:
<h1 class="h3 mb-3 font-weight-normal" th:text="#{login.tip}">Please sign in</h1> <input type="text" class="form-control" th:placeholder="#{login.username}" required="" autofocus=""> <input type="password" class="form-control" th:placeholder="#{login.password}" required="">
-
在中英文按钮上,实现请求参数的变化
<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>
-
自定义一个国际化组件,LocalResolver
@Override public Locale resolveLocale(HttpServletRequest request) { //获取请求中的语言参数 String language = request.getParameter("l"); //如果没有就使用默认的 Locale locale=Locale.getDefault(); //如果请求的链接携带了国际化的参数 if(!StringUtils.isEmpty(language)){ //zh_CN String[] split = language.split("_"); //国家、地区 locale = new Locale(split[0],split[1]); } return locale; }
-
将组件配置到容器中
@Bean public LocaleResolver localeResolver(){ return new MyLocalResolver(); }
3. 登录功能的实现
-
表单是实现提交和验证的关键,先在表单上加一个请求,同时要给输入栏添加name属性以便判断
<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> <input type="text" name="username" class="form-control" th:placeholder="#{login.username}" required="" autofocus=""> <input type="password" name="password" class="form-control" th:placeholder="#{login.password}" required="">
-
Controller层实现判断和跳转,同时添加登录错误信息
@Controller public class loginController { @RequestMapping("user/login") public String login(@RequestParam("username") String username, @RequestParam("password") String password, Model model){ //具体业务 if(!StringUtils.isEmpty(username) && "123456".equals(password)){ return "dashboard"; } else{ //告诉用户你登录失败了 model.addAttribute("msg","用户名或者密码错误"); return "index"; } } }
-
通过if语句智能登录错误信息
<!--如果msg的值为空 则不显示消息--> <p style="color: red" th:text="${msg}" th:if="${not #strings.isEmpty(msg)}"></p>
-
符合真实开发小技巧:登录成功之后域名显示了,修改:
-
registry.addViewController("/main.html").setViewName("dashboard");
-
if(!StringUtils.isEmpty(username) && "123456".equals(password)){ return "redirect:/main.html"; }
-
4. 登录拦截器
-
将正确的登录信息存入session
session.setAttribute("loginUser",username);
-
编写拦截器类
public class LoginHnadlerInterceptor implements HandlerInterceptor { @Override public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { //登录成功之后,应该有用户session; Object loginUser = request.getSession().getAttribute("loginUser"); if(loginUser==null){ request.setAttribute("msg","没有访问权限,请先登录"); request.getRequestDispatcher("/index.html").forward(request,response); return false; } else { return true; } } }
-
拦截器加入配置
@Override public void addInterceptors(InterceptorRegistry registry) { registry.addInterceptor(new LoginHnadlerInterceptor()).addPathPatterns("/**") .excludePathPatterns("/index.html","/","/user/login","/css/*","/js/**","/img/**"); }
5. 员工列表展示
-
修改员工管理按钮,增加事件
<li class="nav-item"> <a class="nav-link" th:href="@{/emps}" > 员工管理 </a> </li>
-
Controller实现查询所有员工
@Controller public class EmployeeController { @Autowired EmployeeDao employeeDao; //查询所有员工 @RequestMapping("/emps") public String list(Model model) { Collection<Employee> employees = employeeDao.getAll(); model.addAttribute("emps",employees); return "emp/list"; } }
-
进行代码复用
-
新建一个文件夹common和文件commons,在里面将公共模板部门用th:fragment抽取
<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="http://getbootstrap.com/docs/4.0/examples/dashboard/#">Company name</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" href="http://getbootstrap.com/docs/4.0/examples/dashboard/#">注销</a> </li> </ul> </nav>
-
在所有需要公共页面的部分用th:replace添加
<div th:replace="~{common/commons::topbar}"></div> <div class="container-fluid"> <div class="row"> <div th:replace="~{common/commons::sidebar}"></div>
-
-
进行选择高亮
-
传递参数给组件
<!--传递参数给组件--> <div th:replace="~{common/commons::sidebar(active='main.html')}"></div>
-
组件接受参数进行判断
<a th:class="${active=='main.html'?'nav-link active':'nav-link '}" th:href="@{/index.html}"> <a th:class="${active=='list.html'?'nav-link active':'nav-link'}" th:href="@{/emps}">
-
-
员工列表展示:通过th:each循环列表展示
<thead> <tr> <th>编号</th> <th>姓名</th> <th>邮箱</th> <th>性别</th> <th>部门</th> <th>生日</th> <th>操作</th> </tr> </thead> <tbody> <tr th:each="emp:${emps}"> <td th:text="${emp.getId()}"></td> <td th:text="${emp.getName()}"></td> <td th:text="${emp.getEmail()}"></td> <td th:text="${emp.getGender()==0?'女':'男'}"></td> <td th:text="${emp.department.getDepartmentName()}"></td> <!--修改时间格式--> <td th:text="${#dates.format(emp.getBirth(),'yyyy-MM-dd HH:mm:ss')}"></td> <td> <button class="btn btn-sm btn-primary">编辑</button> <button class="btn btn-sm btn-danger">删除</button> </td> </tr> </tbody>
6. 增加员工
-
增加按钮实现页面跳转
-
<h2><a class="btn btn-sm btn-success" th:href="@{/emp}">添加员工</a></h2>
-
@GetMapping("/emp") public String toAddPage(Model model){ //查出所有部门的信息 Collection<Department> departments = departmentDao.getDepartment(); model.addAttribute("departments",departments); return "emp/add"; }
-
-
页面添加成功之后返回列表
-
利用post请求才可提交数据到前端
<form th:action="@{/emp}" method="post" > <div class="form-group"> <label>LastName</label> <input type="text" name="name" class="form-control" placeholder="海绵宝宝"> </div> <div class="form-group"> <label>Email</label> <input type="email" name="email" class="form-control" placeholder="1176244270@qq.com"> </div> <div class="form-group"> <label>Gender</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>department</label> <select class="form-control" name="department.id"> <option th:each="dept:${departments}" th:text="${dept.getDepartmentName()}" th:value="${dept.getId()}"></option> </select> </div> <div class="form-group"> <label>Birth</label> <input type="text" name="birth" class="form-control" placeholder="嘤嘤嘤"> </div> <button type="submit" class="btn btn-primary">添加</button> </form>
-
重定向刷新页面
@PostMapping("/emp") //这个无所谓 用post和request都可以的 public String addEmp(Employee employee){ //添加的操作 employeeDao.save(employee);//调用底层业务方法保存员工业务信息 return "redirect:/emps"; }
-
注意:
- 登录是一种数据上的传递和验证功能,故不用post
- 增加完全是一种数据提交了,所以用post
7. 修改员工
-
在编辑上添加th:href进行拼接(注:a标签才可以实现跳转 bottom不行)
<a class="btn btn-sm btn-primary" th:href="@{/emp/}+${emp.getId()}">编辑</a>
-
实现页面跳转
//去员工修改页面 @GetMapping("/emp/{id}") public String toUpdateEmp(@PathVariable("id")Integer id,Model model){ //查出原来数据 Employee employee = employeeDao.getEmployeeById(id); model.addAttribute("emp",employee); //查出所有部门的信息 Collection<Department> departments = departmentDao.getDepartment(); model.addAttribute("departments",departments); return "emp/update";
-
将原来的数据显示到修改页面上 (th:value)
<input th:value="${emp.getName()}" type="text" name="name" class="form-control" placeholder="海绵宝宝"> <input th:checked="${emp.getGender()==1}" class="form-check-input" type="radio" name="gender" value="1"> <option th:selected="${dept.getId()==emp.getDepartment().getId()}" th:each="dept:${departments}" th:text="${dept.getDepartmentName()}" th:value="${dept.getId()}"></option>
-
进行修改页面的跳转
<form th:action="@{/updateEmp}" method="post">
-
页面刷新和重定向
@PostMapping("/updateEmp") public String updateEmp(Employee employee){ employeeDao.save(employee); return "redirect:/emps"; }
-
时间格式一定会报错,在properties中设置好自己的时间格式:
#时间格式 spring.mvc.format.date=yyyy-MM-dd
-
修改时间
<input th:value="${#dates.format(emp.getBirth(),'yyyy-MM-dd HH:mm:ss')}" type="text" name="birth" class="form-control" placeholder="嘤嘤嘤">
-
隐藏域:由于修改成功之后的提交还是有默认的自增id,这个时候需要将自增id放入其中
<input type="hidden" name="id" th:value="${emp.getId()}"/>
8. 删除员工
-
删除改为a标签,写跳转
<a class="btn btn-sm btn-danger" th:href="@{/emp/delete}+${emp.getId()}">删除</a>
-
跳转实现 完成!
@RequestMapping("/emp/delete{id}") public String deleteEmp(@PathVariable("id")Integer id){ employeeDao.delete(id); return "redirect:/emps"; }
9. 404&500错误页面
直接在templetes下新建一个error文件夹,然后将404页面和500页面丢进去即可!
10. 注销
-
按钮实现跳转
<a class="nav-link" th:href="@{/user/logout}">注销</a>
-
清除session实现注销
@RequestMapping("/user/logout") public String userlogout(HttpSession session){ session.invalidate(); return "redirect:/index.html"; }