学习来源–>B站 传送门–> 【狂神说Java】SpringBoot最新教程IDEA版通俗易懂
文章目录这部分整理20p~28p的初始员工管理系统完成(伪造数据库,即并未创建真实存在的数据库);
视频中的springboot版本为2.2.0版本;
本次学习时springboot版本使用–>2.5.6版本;
- 1. 准备工作
- 2.首页实现
- 3.国际化
- 4.登录实现
- 5.登陆拦截器配置
- 6.员工列表的展示
- 公共部分代码提取:方式(1)
- 公共部分代码提取:方式(2)
- 切换侧边栏时,对应的高亮显示
- 取得数据进行显示
- 7.添加员工的功能
- 8.修改员工的实现
- 9.删除实现以及404处理
1. 准备工作
首先新建项目;
导入静态资源
css,img,js,这几个文件在bootstrap官网应该可以找到的
本次的项目不使用数据库,而是伪造数据库;
先去pom.xml下导入thymeleaf以及lombok依赖
org.thymeleaf thymeleaf-spring5 org.thymeleaf.extras thymeleaf-extras-java8time org.projectlombok lombok
若没有安装插件,记得去设置中plugins下载安装Lombok插件,安装后记得要重启IDEA
在pojo包下创建Department类;作为部门类;
package com.xiaozhi.pojo;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
//使用lombok注解;生成get,set方法,构造方法,toString()方法.....
@Data
@NoArgsConstructor
@AllArgsConstructor
public class Department {
//部门ID,名称;
private Integer id;
private String departmentName;
}
在pojo包下创建Employee员工类;
package com.xiaozhi.pojo;
import lombok.Data;
import lombok.NoArgsConstructor;
import java.util.Date;
@Data
@NoArgsConstructor
public class Employee {
//员工ID,名称,邮箱,性别;生日
private Integer id;
private String lastName;
private String email;
private Integer sex;
private Date birthday;
//部门;
private Department department;
//构造方法;
public Employee(Integer id, String lastName, String email, Integer sex, Department department) {
this.id = id;
this.lastName = lastName;
this.email = email;
this.sex = sex;
this.department = department;
this.birthday = new Date();
}
}
在dao包下创建DepartmentDao; 作为部门持久层;
这里开始先放两个处理;查所有部门以及根据部门ID查询部门;
package com.xiaozhi.dao;
import com.xiaozhi.pojo.Department;
import java.util.Collection;
import java.util.HashMap;
import java.util.Map;
@Repository
public class DepartmentDao {
//模拟数据库;
private static Map departmens=null;
static {
//创建部门表;
departmens= new HashMap<>();
//添加数据;
departmens.put(100,new Department(100,"人事部"));
departmens.put(101,new Department(101,"财务部"));
departmens.put(102,new Department(102,"研发部"));
departmens.put(103,new Department(103,"开发部"));
departmens.put(104,new Department(104,"产品部"));
}
//对虚拟数据库进行操作;
//获取所有的部门信息;
public Collection findAllDepartment(){
return departmens.values();
}
//根据ID获取部门;
public Department findDepartById(Integer id){
return departmens.get(id);
}
}
在dao包下创建EmployeeDao类; 作为员工持久层;
package com.xiaozhi.dao;
import com.xiaozhi.pojo.Department;
import com.xiaozhi.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 {
//模拟数据库;
private static Map employees = null;
//员工还有对应的部门表;
@Autowired
private DepartmentDao departmentDao;
static {
//创建数据表;
employees = new HashMap<>();
//存放数据;
employees.put(0,new Employee(0,"xiaozhire0","1236547@qq.com",1,new Department(102,"研发部")));
employees.put(1,new Employee(1,"阿杰","1236547@qq.com",0,new Department(103,"开发部")));
employees.put(2,new Employee(2,"大白","asda@qq.com",1,new Department(100,"人事部")));
employees.put(3,new Employee(3,"村头","1237@qq.com",0,new Department(103,"开发部")));
employees.put(4,new Employee(4,"杨树","122547@qq.com",0,new Department(102,"研发部")));
employees.put(5,new Employee(5,"柳树","1326547@qq.com",1,new Department(101,"财务部")));
employees.put(6,new Employee(6,"苹果树","31236547@qq.com",0,new Department(103,"开发部")));
employees.put(7,new Employee(7,"面包","112316547@qq.com",1,new Department(103,"开发部")));
employees.put(8,new Employee(8,"炒面","1231547@qq.com",0,new Department(104,"产品部")));
employees.put(9,new Employee(9,"大话","1231231547@qq.com",1,new Department(104,"产品部")));
}
//做到添加员工时,ID自动递增;
private static Integer initId =10;
//添加员工;
public void addEmployee(Employee employee){
//先看这个员工是否有Id;
if(employee.getId()==null){
employee.setId(initId++);
}
//设置部门;
employee.setDepartment(departmentDao.findDepartById(employee.getDepartment().getId()));
//添加到模拟数据表中;
employees.put(employee.getId(),employee);
}
//获取全部员工;
public Collection findAllEmployees(){
return employees.values();
}
//根据员工Id查员工;
public Employee findEmployeeByEId(Integer id){
return employees.get(id);
}
//根据员工ID删除员工;
public void deleteEmployee(Integer id){
employees.remove(id);
}
}
2.首页实现
在controller包下创建WelcomeController类,控制首页的请求;
package com.xiaozhi.controller;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
@Controller
public class WelcomeController {
//到达首页;
@RequestMapping({"/", "/index.html"})
public String toIndex(){
return "index";
}
}
启动项目;访问http://localhost:8080/时;页面虽然加载,但是css样式表的内容却没内嵌导入;
实际上,这个首页跳转也可以写在自定义配置的config中;
在WelcomeController类中刚才写的请求处理直接删除掉;
然后在config包下创建MyMvcConfig类,自定义一些mvc的配置;
进行视图跳转;
package com.xiaozhi.config;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.ViewControllerRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
@Configuration
public class MyMvcConfig implements WebMvcConfigurer {
//添加视图跳转;
@Override
public void addViewControllers(ViewControllerRegistry registry) {
//跳转首页
registry.addViewController("/").setViewName("index");
registry.addViewController("/index.html").setViewName("index");
}
}
在application.properties下配置关闭模板引擎的缓存;改改虚拟路径;改改端口;
# 关闭模板template的缓存 spring.thymeleaf.cache=false #更改项目的端口 server.port=5277 #更改项目的虚拟目录; server.servlet.context-path=/xiaozhire0
OK,对templates模板下的首页index.html进行改造
Signin Template for Bootstrap
清除浏览器缓存,访问http://localhost:5277/xiaozhire0/时即可加载到样式;
3.国际化OK,把其他几个页面的链接资源导入路径地址也改一改;
也就是说,你做的项目至少有两套语言;比如说中英文切换;
—>Dubbo官网
–>Dubbo文档
那么,开始吧;首先保证自己的配置文件默认有支持UTF-8;
确认没问题后;
在resources目录下创建i18n文件夹;注意不要建错路径了哦
那么,你知道为啥创建的文件夹叫i18n?
国际化–>对应英文internationalization;i和n之间有18个单词;所以简写为i18n
OK,在i18n目录下创建login.properties文件;以及login_zh_CN.properties文件
诶;他们两个合并了;
那么,你就可以直接右键Resources Bundle'login',来添加文件了
添加en_UsS试试;
诶,自动识别英文;
生成配置文件
打开这几个创建的文件在IDEA中点击下面的Resource Bundle;就能做到可视化配置
比如说;我添加了一个login.tip;这边就自动生成了;
点击左下角的Text,这时已经存在;
是不是很方便呢
OK,接着回到可视化;默认配置为中文显示;然后编写对应的中英文文件;
哈哈哈;这个实际上就是键值对配置对应了
切换到几个文件的Text看看;是不是已经自动配置了呢;一次性写了三个配置文件;
OK,那么继续做其他的中英文配置吧;
OK,首页登录的中英文切换配置基本结束;
到这里,当然还不能完全做到转换;
在IDEA中;按照Ctrl+Shift+Alt+N,切换到Classes搜索MessageSourceAutoConfiguration类;
这里有提到MessageSourceProperties配置文件类;Ok,那就去这个类看看
这里有提到编码为UTF-8
那么怎么配置国际化呢?
打开application.properties配置文件;添加配置;#配置读取位置; spring.messages.basename=i18n.login根据配置文档的thymeleaf模板引擎表达式提示,需要在跳转链接处使用#{… }
OK,那就去index.html修改链接吧;设置时有提示.
OK,剩下的几个也改改;这时访问的默认显示就好了;
OK,这个基础默认显示算是完成了;那么具体还要做到点击下面的中英文时切换对应版本的配置语言;才算真正完成;
全局搜索这个WebMvcAutoConfiguration类;找到其中的静态内部类EnableWebMvcConfiguration;
其中有这个localeResolver()方法;
2.5.6版本2.2.0版本
源码这部分和之前的有所不同;
前面判断是否有自己配置的,所有,就走前面自己配置的;
否则根据AcceptHeaderLocaleResolver类进行配置;
这个类有实现接口LocaleResolver;大概可以理解为,实现这个接口后,实现类就可进行国际化配置功能;
回到首页index.html;先在index.html添加切换的链接请求;
然后,去自定义解析实现类试试;
在config包下创建MyLocaleResolver类;
package com.xiaozhi.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) {
//获取请求的参数;注意;l这里就是语言的简写;
String language = request.getParameter("l");
//获取默认的解析; 也就是保证,若没配置就用默认的;
Locale locale = Locale.getDefault();
//判断得到的参数值是不是为空的
if(!StringUtils.isEmpty(language)){
//若不未空,就得切割字符串了; 通过 "_"分为国家和地区的两部分数组;
String[] s = language.split("_");
locale = new Locale(s[0], s[1]);
}
return locale;
}
//这里不写,直接空实现;
@Override
public void setLocale(HttpServletRequest request, HttpServletResponse response, Locale locale) {
}
}
当然,还要把自定义的解析器注入到容器中;
在MyMvcConfig类中进行;
package com.xiaozhi.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.ViewControllerRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
@Configuration
public class MyMvcConfig implements WebMvcConfigurer {
//添加视图跳转;
@Override
public void addViewControllers(ViewControllerRegistry registry) {
//跳转首页
registry.addViewController("/").setViewName("index");
registry.addViewController("/index.html").setViewName("index");
}
//将自定义的国际化组件解析器注入容器;
@Bean
public LocaleResolver localeResolver(){
return new MyLocaleResolver();
}
}
4.登录实现启动项目主程序,访问首页,点击下面的中文/English即可完成语言切换了;
先把index.html下的提交地址请求链接改一下;
在controller包下创建LoginController类;
package com.xiaozhi.controller;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
@Controller
public class LoginController {
@RequestMapping("/users/login")
@ResponseBody
public String toLogin(){
return "测试可访问--->";
}
}
先进行测试一下,请求是否有效;
启动项目主程序;填充用户名与密码之后,看看是否可跳转;
OK,请求跳转可行;继续操作;
注意index.html页面的输入框是否加了name属性;
修改LoginController里面的处理;
package com.xiaozhi.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;
@Controller
public class LoginController {
@RequestMapping("/users/login")
public String toLogin(@RequestParam("username")String username,
@RequestParam("password")String password,
Model model){
//之前就用的伪造数据库;但是登录用户没做伪造数据;登录用户这里直接判断写死;
if(!StringUtils.isEmpty(username) && password.equals("qqq")){
//跳转页面;
return "redirect:/mian.html";
}else {
//失败时提示;
model.addAttribute("message","密码错误");
//回到登录页面;
return "index";
}
}
}
在index.html处添加消息回显;登录错误时显示提示;
可以在MyMvcConfig类中,再添加一个主页面的视图跳转的路径;
registry.addViewController("/mian.html").setViewName("dashboard");
5.登陆拦截器配置启动项目;测试登录;
先在LoginController类中的登录请求处理中;进行添加session会话,登录时将用户的用户名存入session;
package com.xiaozhi.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("/users/login")
public String toLogin(@RequestParam("username")String username,
@RequestParam("password")String password,
Model model, HttpSession session){
//之前就用的伪造数据库;但是登录用户没做伪造数据;登录用户这里直接判断写死;
if(!StringUtils.isEmpty(username) && password.equals("qqq")){
//存入session;
session.setAttribute("user",username);
//跳转页面;
return "redirect:/mian.html";
}else {
//失败时提示;
model.addAttribute("message","密码错误");
//回到登录页面;
return "index";
}
}
}
在config包下创建MyLoginIntercept
package com.xiaozhi.config;
import org.springframework.web.servlet.HandlerInterceptor;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
public class MyLoginIntercept implements HandlerInterceptor {
//拦截之前的处理;
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
//登录后,取到用户的会话session;
String user = (String) request.getSession().getAttribute("user");
//若不登录,就拦截;
if(user == null){
//提示;
request.setAttribute("message","无权限,请登录");
//跳转返回首页;
request.getRequestDispatcher("/index.html").forward(request,response);
return false;
}else {
return true;
}
}
}
在MyMvcConfig类中添加配置拦截器的方法;
//配置拦截器;
@Override
public void addInterceptors(InterceptorRegistry registry) {
//将自定义的拦截器存入; 过滤所有请求,排除指定的请求(登录,首页显示,静态资源...);
registry.addInterceptor(new MyLoginIntercept()).addPathPatterns("
@Controller
public class EmployeeController {
@Autowired
EmployeeDao employeeDao;
@RequestMapping("/employees")
public String employeeList(Model model){
//调用方法;
Collection allEmployees =
employeeDao.findAllEmployees();
//添加属性;
model.addAttribute("employees",allEmployees);
//转到页面;
return "emp/list";
}
}
公共部分代码提取:方式(1)启动项目,登录测试一下;
点击员工管理显示
公共部分代码提取:方式(2)OK;可以注意到dashboard.html和list.html的侧边栏是相同的,想办法得去抽取出公共的部分;
在dashboard.html中进行抽取;
在list.html中,先删除原来的侧边栏;然后插入提取的公共部分侧边栏
那么顶部栏当然也可以提取出来;类似于侧边栏的提取过程;
在dashboard.html中提取公共的顶部栏
在list.html中删掉原来的侧边栏;引入提取的公共部分的侧边栏;
启动项目;进行测试效果,
OK,提取公共部分代码是可行的;提高了代码的复用;
实际上,提取公共部分的时候;还可以更加简洁一点;
直接把公共部分的代码单独取出来,放到一个文件中;然后让dashboard.html和list.html一起引用;
Ok,在templates模板目录下创建commons文件夹;然后创建commons.html文件
commons.html
在dashboard.html中引入抽取的公共部分代码;
同样地;在list.html中引入公共部分的代码;
启动项目,测试是否可行;
OK,继续操作
切换侧边栏时,对应的高亮显示
点击员工管理显示时;注意到,它并没有高亮显示;而页面中的是否高亮,是由是否写了这个active决定的;
但是,把侧边栏全部都提取到一块了;要怎么做到点击时的显示呢?
进行解决:—>
在引用提取公共代码的时候,去试试传递参数;
在dashboard.html中引用公共侧边栏时;
在list.html中引入公共侧边栏时;
取得数据进行显示在commons.html中;
启动项目,进行测试使用;
点击员工管理显示时,有高亮显示;
OK,前面几项的基本完成后,该进行数据显示了.
最终的显示是要放在list.html页面的这部分的;但是数据肯定不能写死,要动态的存取
OK,进行取值;
表格的这部分代码
| id | lastName | sex | birthday | department | |
|---|---|---|---|---|---|
启动项目,测试员工显示列表;
那么,根据这类管理系统来看的话,后期还有进行添加删除,修改…的操作;
那么写个样式;
启动项目,看看效果
出生日期的显示格式,可以改一改
启动项目,看看效果;
7.添加员工的功能
在list.html页面中添加链接;
启动项目;查看效果;
在controller包下的EmployeeController中添加 跳转到添加页面的 处理请求的方法;
//装配部门处理;
@Autowired
DepartmentDao departmentDao;
//跳转到添加的页面;Get请求;
@GetMapping("/addemployee")
public String addEmployee(Model model){
//获取所有的部门;
Collection allDepartment = departmentDao.findAllDepartment();
//传递返回;
model.addAttribute("allDepartment",allDepartment);
return "emp/add";
}
还没有添加的页面,去bootstrap网找个添加的表单https://www.bootcss.com/
基本页面和list.html差不多;
但是主要内容;更改为表单
在emp文件夹下创建add.html
主要表单部分
在controller包下的EmployeeController中添加 接收提交表单 处理请求的方法,并且显示到列表;
//提交表单数据;Post请求处理
@PostMapping("/addemployee")
public String addSuccess(Employee employee){
//调用方法;
employeeDao.addEmployee(employee);
//重定向到显示的列表;
return "redirect:/employees";
}
OK,启动项目,可测试
提交后,有显示–>
8.修改员工的实现但是有一点问题,就是日期提交时若是格式为年-月 - 日-的话;就有错误了;
有错误
什么问题呢;还记得这个默认配置的格式吧;
那么就得去application.properties里面配置一下日期格式了;#配置日期格式; spring.mvc.format.date=yyyy-MM-ddOK,再去启动项目,测试使用;
添加成功
list.html点击修改时跳转链接
修改
在EmployeeController下添加跳转到修改页面的方法
//跳转到员工的修改页面; 携带有ID
@GetMapping("/update/{id}")
public String toUpdate(@PathVariable("id")Integer id,Model model){
//根据ID查出员工信息;
Employee employeeByEId = employeeDao.findEmployeeByEId(id);
//返回数据;
model.addAttribute("thisEmployee",employeeByEId);
//获取所有的部门;
Collection allDepartment = departmentDao.findAllDepartment();
//传递返回;
model.addAttribute("allDepartment",allDepartment);
return "emp/update";
}
在emp文件夹下创建update.html;注意这个更新页面打开时,有用户的初始信息;
该页面可复用添加页面,修改主要的表单即可;
main;主要的表单部分
在EmployeeController下添加修改的方法
//进行修改处理;
@PostMapping("/update/do")
public String updateEmployee(Employee employee){
//调用方法;
employeeDao.addEmployee(employee);
//重定向到显示的列表;
return "redirect:/employees";
}
启动项目,进行测试
比如说,我去修改面包
它的信息被取到了
9.删除实现以及404处理修改:
Ok,修改成功
在list.html页面的删除链接处添加请求;
删除
在EmployeeController类中添加删除的处理方法
//删除员工处理
@GetMapping("/delete/{id}")
public String deleteEmployee(@PathVariable("id")Integer id){
//调用方法;
employeeDao.deleteEmployee(id);
//重定向到显示的列表;
return "redirect:/employees";
}
启动项目,测试;删除成功
OK;关于404问题的页面处理;
在templates模板下创建error文件夹;将404.html页面文件放入
测试,即可跳转
页面注销实现
在公共代码文件commons.html的头部导航栏位置;添加请求链接
在controller包下的LoginController类中进行请求处理;添加方法;
//注销
@RequestMapping("/users/logout")
public String toLogout(){
//销毁session;
//回到登录页;
return "redirect:/index.html";
}
OK,启动项目,测试效果
暂时结束



