Spring|Spring Boot(九)--------员工管理系统

Spring Boot(九)--------员工管理系统 18、员工管理系统 18.1 准备工作
18.1.1 前端页面

  • 将html页面放入templates文件夹
  • 将css,js,img放入static文件夹
18.1.2 实体类编写
  • Department
public class Department { private Integer id; private String departmentName; public Department() {}public Department(Integer id, String departmentName) { this.id = id; this.departmentName = departmentName; }public Integer getId() { return id; }public void setId(Integer id) { this.id = id; }public String getDepartmentName() { return departmentName; }public void setDepartmentName(String departmentName) { this.departmentName = departmentName; }@Override public String toString() { return "Department{" + "id=" + id + ", departmentName='" + departmentName + '\'' + '}'; } }

  • Employee
import java.util.Date; public class Employee { private Integer id; private String lastName; private String email; private Integer gender; //0女 1男 private Department department; private Date birth; public Employee() { }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(); } ... }

18.1.3 Dao层模拟数据库
  • DepartmentDao
public class DepartmentDao { //模拟数据库中的数据 private static Map departments = null; static{ //创建一个部门表 departments = new HashMap(); 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 getDepartments(){ return departments.values(); }//根据id得到部门 public Department getDepartmentById(Integer id){ return departments.get(id); } }

  • EmployeeDao
public class EmployeeDao { //模拟数据库中的数据 private static Map employees = null; //员工所属部门 private DepartmentDao departmentDao; static { //创建一个员工表 employees = new HashMap(); employees.put(1001, new Employee(1001, "zzz", "23656@qq.com", 1, new Department(101, "后勤部"))); employees.put(1002, new Employee(1002, "mmm", "12345@qq.com", 0, new Department(102, "市场部"))); employees.put(1003, new Employee(1003, "ttt", "67890@qq.com", 1, new Department(103, "教研部"))); employees.put(1004, new Employee(1004, "aaa", "98765@qq.com", 0, new Department(101, "后勤部"))); employees.put(1005, new Employee(1005, "bbb", "43210@qq.com", 1, new Department(102, "市场部"))); employees.put(1006, new Employee(1006, "ccc", "00000@qq.com", 0, new Department(101, "后勤部"))); } //增加一个员工,主键自增 private static Integer initId = 1007; public void save(Employee employee){ if(employee.getId()==null){ employee.setId(initId++); } employee.setDepartment(departmentDao.getDepartmentById(employee.getDepartment().getId())); employees.put(employee.getId(),employee); }//查询全部员工信息 public Collection getAll(){ return employees.values(); }//通过Id查询员工 public Employee getEmployeeById(Integer id){ return employees.get(id); }//删除员工 public void delete(Integer id){ employees.remove(id); } }

18.1.4 pom.xml
  • 添加themeleaf的依赖
4.0.0org.springframework.boot spring-boot-starter-parent 2.6.4 com.zmt springboot-03-web02 0.0.1-SNAPSHOT springboot-03-web02 Demo project for Spring Boot1.8 org.springframework.boot spring-boot-starter-web org.springframework.boot spring-boot-starter-test >test org.springframework.boot spring-boot-starter-thymeleaf org.springframework.boot spring-boot-maven-plugin

18.1.5 目录结构 Spring|Spring Boot(九)--------员工管理系统
文章图片

18.2 首页实现
18.2.1 第一种方式
  • 创建一个IndexController,不建议使用
@Controller public class IndexController { @RequestMapping({"/","/index.html"}) public String index(){ return "index"; } }

18.2.2 第二种方式
  • 创建config,新建MyMvcConfig类,重写addViewControllers()方法
@Configuration public class MyMvcConfig implements WebMvcConfigurer { @Override public void addViewControllers(ViewControllerRegistry registry) { registry.addViewController("/").setViewName("index"); registry.addViewController("/index.html").setViewName("index"); } }

18.3 加载静态资源
  • 导入thymeleaf包

  • 将所有页面的静态资源使用thymeleaf接管
Spring|Spring Boot(九)--------员工管理系统
文章图片
type="text/javascript" th:src="https://www.it610.com/article/@{/js/jquery-3.2.1.slim.min.js}"> type="text/javascript" th:src="https://www.it610.com/article/@{/js/popper.min.js}"> type="text/javascript" th:src="https://www.it610.com/article/@{/js/bootstrap.min.js}">type="text/javascript" th:src="https://www.it610.com/article/@{/js/feather.min.js}">type="text/javascript" th:src="https://www.it610.com/article/@{/js/Chart.min.js}">

  • 静态资源目录
Spring|Spring Boot(九)--------员工管理系统
文章图片

18.4 页面国际化
  • 很多时候,网站会涉及多语言切换,所以需要学习页面国际化
18.4.1 准备工作
  • 在IDEA中统一设置properties的编码问题
Spring|Spring Boot(九)--------员工管理系统
文章图片

18.4.2 配置文件编写
  • resources文件夹下新建一个i18n文件夹,用于存放国际化配置文件
  • i18n:internationalization,从开头字母i到结尾字母n中间有18个字母
  • 新建一个login.properties文件和login_zh_CN.properties。发现IDEA自动世界了我们要做国际化的操作,文件夹发生了变化,自动生成了一个文件夹
Spring|Spring Boot(九)--------员工管理系统
文章图片

  • 可以继续添加其他语言的配置文件,右键生成的文件夹
Spring|Spring Boot(九)--------员工管理系统
文章图片

  • 添加步骤
Spring|Spring Boot(九)--------员工管理系统
文章图片

  • IDEA中有一种方式:Resource Bundle,点击可以进行可视化配置,即配置该登录页面所有方式的多语言模式
Spring|Spring Boot(九)--------员工管理系统
文章图片

  • 添加之后,可以看到login.properties文件中出现login.tip=请登录
Spring|Spring Boot(九)--------员工管理系统
文章图片

  • 继续添加其他内容,包括页面提示,页面按钮等
Spring|Spring Boot(九)--------员工管理系统
文章图片

  • 查看此时的配置文件login.properties,其中为打开页面的默认值
login.btn=登录 login.password=密码 login.remember=记住我 login.tip=请登录 login.username=用户名

  • 查看英文配置文件login_en_US.properties
login.btn=Sign in login.password=password login.remember=remember me login.tip=please sign in login.username=username

  • 查看中文配置文件login_zh_CN.properties
login.btn=登录 login.password=密码 login.remember=记住我 login.tip=请登录 login.username=用户名

  • 完成页面国际化配置
18.4.3 国际化配置文件生效探究
  • 查看Spring Boot源码中对国际化的自动配置,查看类MessageSourceAutoConfiguration
  • 其中的messageSource()方法,获取了properties传递过来的值
@Bean public MessageSource messageSource(MessageSourceProperties properties) { ResourceBundleMessageSource messageSource = new ResourceBundleMessageSource(); if (StringUtils.hasText(properties.getBasename())) { messageSource.setBasenames(StringUtils .commaDelimitedListToStringArray(StringUtils.trimAllWhitespace(properties.getBasename()))); } if (properties.getEncoding() != null) { messageSource.setDefaultEncoding(properties.getEncoding().name()); } messageSource.setFallbackToSystemLocale(properties.isFallbackToSystemLocale()); Duration cacheDuration = properties.getCacheDuration(); if (cacheDuration != null) { messageSource.setCacheMillis(cacheDuration.toMillis()); } messageSource.setAlwaysUseMessageFormat(properties.isAlwaysUseMessageFormat()); messageSource.setUseCodeAsDefaultMessage(properties.isUseCodeAsDefaultMessage()); return messageSource; }

  • 我们放在了i18n目录下,在application.properties文件中配置对应的message路径
spring.messages.basename=i18n.login

18.4.5 配置页面国际化
  • 查看页面代码,找到对应的message取值操作,修改为#{...}
  • 例如:
Please sign in

  • 修改后页面的乱码,多语言问题都解决了
Spring|Spring Boot(九)--------员工管理系统
文章图片

18.4.6 配置国际化源码探究
  • 现在需要探究,如何可以点击按钮实现双语切换
  • 打开WebMvcAutoConfig类,找到localeResolver()方法
public LocaleResolver localeResolver() { if (this.webProperties.getLocaleResolver() == WebProperties.LocaleResolver.FIXED) { return new FixedLocaleResolver(this.webProperties.getLocale()); } AcceptHeaderLocaleResolver localeResolver = new AcceptHeaderLocaleResolver(); localeResolver.setDefaultLocale(this.webProperties.getLocale()); return localeResolver; }

  • 其中,如果手动配置了本地区域化,就返回用户配置的信息,如果没有手动配置,返回默认的配置信息,默认配置信息在AcceptHeaderLocaleResolver类中,其中有一个resolveLocale()方法
@Override public Locale resolveLocale(HttpServletRequest request) { Locale defaultLocale = getDefaultLocale(); if (defaultLocale != null && request.getHeader("Accept-Language") == null) { return defaultLocale; } Locale requestLocale = request.getLocale(); List supportedLocales = getSupportedLocales(); if (supportedLocales.isEmpty() || supportedLocales.contains(requestLocale)) { return requestLocale; } Locale supportedLocale = findSupportedLocale(request, supportedLocales); if (supportedLocale != null) { return supportedLocale; } return (defaultLocale != null ? defaultLocale : requestLocale); }

  • 需要自己建立一个国际化解析器,来让刚才写的配置文件生效
  • 先修改一下前端页面的跳转链接
中文 English

  • 新建MyLocaleResolver组件类
public class MyLocaleResolver implements LocaleResolver { //解析请求 @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; }@Override public void setLocale(HttpServletRequest request, HttpServletResponse response, Locale locale) {} }

  • 在我们自己写的MyMvcConfig中添加bean,使这个组件生效
//把自定义的国际化组件放进来 @Bean public LocaleResolver localeResolver(){ return new MyLocaleResolver(); }

  • 实现了可以根据自己的需求,来切换中英文
Spring|Spring Boot(九)--------员工管理系统
文章图片

Spring|Spring Boot(九)--------员工管理系统
文章图片

18.4.7 小结
  • 首页配置:注意点,所有的静态资源页面都需要用@thymeleaf接管,url:@{}
  • 页面国际化
    • 需要配置i18n文件夹
    • 如果需要在项目中进行按钮自动切换,需要自定义一个组件LocaleResolver
    • 将自己写的组件配置到Spring容器@Bean
    • #{}
18.5 登录页面
  • 新建LoginController登录验证
@Controller public class LoginController { @RequestMapping("/user/login") @ResponseBody public String login(@RequestParam("username") String username, @RequestParam("password") String password, Model model){ //具体业务(判断用户名是否为空等) //用户名不为空 且 密码为123456 if(!StringUtils.isEmpty(username) && "123456".equals(password)){ return "dashboard"; }else{ //告诉用户你登录失败了 model.addAttribute("msg","用户名或密码错误"); return "index"; } } }

  • 修改首页表单,增加登录失败时的信息显示,p标签

  • 此时,页面并不友好,在地址栏可以看到你的账号和密码,解决密码泄露问题
  • MyMvcConfig类中,添加main映射
@Override public void addViewControllers(ViewControllerRegistry registry) { registry.addViewController("/").setViewName("index"); registry.addViewController("/index.html").setViewName("index"); registry.addViewController("/main.html").setViewName("dashboard"); }

  • 修改LoginController的跳转页面(redirect跳转)
@Controller public class LoginController { @RequestMapping("/user/login") public String login(@RequestParam("username") String username, @RequestParam("password") String password, Model model){ //具体业务(判断用户名是否为空等) //用户名不为空 且 密码为123456 if(!StringUtils.isEmpty(username) && "123456".equals(password)){ return "redirect:/main.html"; }else{ //告诉用户你登录失败了 model.addAttribute("msg","用户名或密码错误"); return "index"; } } }

  • 此时输入localhost:8080/main.html就可以直接进入页面了,需要使用拦截器阻止直接访问
18.6 登录拦截器
  • LoginController中添加一个session进行判断
@Controller public class LoginController { @RequestMapping("/user/login") public String login(@RequestParam("username") String username, @RequestParam("password") String password, Model model, HttpSession session){ //具体业务(判断用户名是否为空等) //用户名不为空 且 密码为123456 if(!StringUtils.isEmpty(username) && "123456".equals(password)){ session.setAttribute("loginUser",username); return "redirect:/main.html"; }else{ //告诉用户你登录失败了 model.addAttribute("msg","用户名或密码错误"); return "index"; } } }

  • config文件夹下新建一个LoginHandlerInterceptor拦截器
public class LoginHandlerInterceptor 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; } } }

  • MyMvcConfig中重写拦截器方法,记得过滤静态资源,否则渲染效果会消失
@Override public void addInterceptors(InterceptorRegistry registry) { registry.addInterceptor(new LoginHandlerInterceptor()) .addPathPatterns("/**") .excludePathPatterns("/index.html","/","/user/login","/css/**","/js/**","/img/**"); }

  • dashboard.html页面中修改登录信息为[[ ${session.loginUser} ]],这样登录后会显示用户名
[[ ${session.loginUser} ]]

  • 使用try用户名登录成功,可以看到用户名显示在左上角
Spring|Spring Boot(九)--------员工管理系统
文章图片

  • 密码错误登录失败时
Spring|Spring Boot(九)--------员工管理系统
文章图片

18.7 员工列表展示
18.7.1 提取公共页面
  • 前端页面中,有一部分是多个页面公共使用的,可以抽取公共代码方便调用,在list.htmldashboard.html中抽取公共部分代码
  • 发现页面公共部分为顶部导航栏和侧边栏

  • 提取公共代码,在templates目录下创建commons目录,在该目录下创建commons.html用于存放公共页面代码

  • dashboard.htmllist.html可以直接调用公共部分代码显示页面

  • 注:replace和insert效果一样,但是insert会多套一层div标签
18.7.2 添加侧边栏点亮
  • dashboard.htmllist.html页面中侧边栏传参

  • commons.html中接收参数并判断

18.7.3 后台编写
  • 新建EmployController员工管理后台
@Controller public class EmployeeController { @Autowired EmployeeDao employeeDao; @RequestMapping("/emps") public String list(Model model){ Collection employees = employeeDao.getAll(); model.addAttribute("emps",employees); return "emp/list"; } }

  • 注意:如果employeeDao爆红,去EmployeeDao类中,加上注解@Repository
  • 修改前端公共页面页面中的链接@{/emps}`

18.7.4 列表循环展示
  • list.html添加,自己的数据循环
Section title
id lastName email gender department birth 操作

  • 此时项目结构
Spring|Spring Boot(九)--------员工管理系统
文章图片

  • 页面展示
Spring|Spring Boot(九)--------员工管理系统
文章图片

18.8 添加员工信息
18.8.1 提交按钮
  • list.html页面添加提交按钮
添加员工

18.8.2 跳转添加页面
  • 点击添加按钮,跳转到添加信息页面
  • add.html页面编写,其余部分代码和list.html相同,只需修改main标签中的代码

class="form-control" name="department.id">

  • EmployeeController中编写跳转到添加页的toAddPage()方法
@GetMapping("/emp") public String toAddPage(Model model){ //查出所有部门的信息 Collection department = departmentDao.getDepartments(); model.addAttribute("departments",department); return "emp/add"; }

18.8.3 添加操作
  • EmployeeController中编写addEmp()方法
//添加员工 @PostMapping("/emp") public String addEmp(Employee employee){ //添加的操作 employeeDao.save(employee); return "redirect:/emps"; }

  • 添加信息页面
Spring|Spring Boot(九)--------员工管理系统
文章图片

  • 添加成功
Spring|Spring Boot(九)--------员工管理系统
文章图片

18.9 修改员工信息
18.9.1 修改按钮
  • list.html中添加编辑按钮
编辑

18.9.2 跳转修改页面
  • update.html编写,只需修改main标签中的代码,其他和list.html代码相同

class="form-control" name="department.id">

  • 跳转到update.html页面,EmployeeController中编写toUpdateEmp()方法
//跳转到修改页面 @GetMapping("/emp/{id}") public String toUpdateEmp(@PathVariable("id") Integer id, Model model){ //查出修改前数据 Employee employee = employeeDao.getEmployeeById(id); model.addAttribute("emp",employee); //查出所有部门的信息 Collection department = departmentDao.getDepartments(); model.addAttribute("departments",department); return "emp/update"; }

18.9.3 修改操作
  • EmployeeController中编写updateEmp()方法
//修改方法 @RequestMapping("/updateEmp") public String updateEmp(Employee employee){ //把修改后的信息再次保存 employeeDao.save(employee); return "redirect:/emps"; }

  • 修改成功
Spring|Spring Boot(九)--------员工管理系统
文章图片

18.10 删除员工信息
18.10.1 删除按钮
  • list.html中添加删除按钮
删除

18.10.2 删除操作
  • EmployeeController中编写deleteEmp()方法
//删除方法 @GetMapping("/delemp/{id}") public String deleteEmp(@PathVariable("id")int id){ employeeDao.delete(id); return "redirect:/emps"; }

  • 删除成功,删除了1004号
Spring|Spring Boot(九)--------员工管理系统
文章图片

18.11 404页面
  • 404.html页面放入到templates目录中的error目录中
  • 目录结构
Spring|Spring Boot(九)--------员工管理系统
文章图片

18.12 注销
  • commons.html中添加注销按钮
注销

  • LoginController.java中编写注销页面代码
//注销 @RequestMapping("/user/logout") public String logout(HttpSession session){ session.invalidate(); return "redirect:/index"; }

  • 注销实现
【Spring|Spring Boot(九)--------员工管理系统】Spring|Spring Boot(九)--------员工管理系统
文章图片

18.13 如何开发一个网站
18.13.1 准备
  • 前端涉及:页面具体样式
  • 前端框架组件:Bootstrap、Layui、semantic-ui
  • 设计数据库
  • 前端能独立运行,独立化工程
  • 数据接口如何对接:json,对象
  • 前后端联调测试
18.13.2 开发
  • 有一套自己熟悉的后台模板:工作必须!推荐后台框架:x-admin
  • 前端页面:至少自己能够通过前端框架,组合出来一个网站页面
  • 让这个网站可以独立运行

    推荐阅读