狂神Spring Boot 员工管理系统 【源码 + 笔记 + web素材】 超详细整理

最后

文章中涉及到的知识点我都已经整理成了资料,录制了视频供大家下载学习,诚意满满,希望可以帮助在这个行业发展的朋友,在论坛博客等地方少花些时间找资料,把有限的时间,真正花在学习上,所以我把这些资料,分享出来。相信对于已经工作和遇到技术瓶颈的朋友们,在这份资料中一定都有你需要的内容。

本文已被CODING开源项目:【一线大厂Java面试题解析+核心总结学习笔记+最新讲解视频+实战项目源码】收录

需要这份系统化的资料的朋友,可以点击这里获取

我们去看一下SpringBoot对国际化的自动配置!这里又涉及到一个类:MessageSourceAutoConfiguration

里面有一个方法,这里发现SpringBoot已经自动配置好了管理我们国际化资源文件的组件 ResourceBundleMessageSource;

// 获取 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目录下,所以我们要去配置这个messages的路径;

spring.messages.basename=i18n.login

配置页面国际化值

去页面获取国际化的值,查看Thymeleaf的文档,找到message取值操作为:#{…}。我们去页面测试下:

IDEA还有提示,非常智能的!

在这里插入图片描述

我们可以去启动项目,访问一下,发现已经自动识别为中文的了!

在这里插入图片描述

但是我们想要更好!可以根据按钮自动切换中文英文!

配置国际化解析

在Spring中有一个国际化的Locale (区域信息对象);里面有一个叫做LocaleResolver (获取区域信息对象)的解析器!

我们去我们webmvc自动配置文件,寻找一下!看到SpringBoot默认配置:

@Bean

@ConditionalOnMissingBean

@ConditionalOnProperty(prefix = “spring.mvc”, name = “locale”)

public LocaleResolver localeResolver() {

// 容器中没有就自己配,有的话就用用户配置的

if (this.mvcProperties.getLocaleResolver() == WebMvcProperties.LocaleResolver.FIXED) {

return new FixedLocaleResolver(this.mvcProperties.getLocale());

}

// 接收头国际化分解

AcceptHeaderLocaleResolver localeResolver = new AcceptHeaderLocaleResolver();

localeResolver.setDefaultLocale(this.mvcProperties.getLocale());

return localeResolver;

}

AcceptHeaderLocaleResolver 这个类中有一个方法

public Locale resolveLocale(HttpServletRequest request) {

Locale defaultLocale = this.getDefaultLocale();

// 默认的就是根据请求头带来的区域信息获取Locale进行国际化

if (defaultLocale != null && request.getHeader(“Accept-Language”) == null) {

return defaultLocale;

} else {

Locale requestLocale = request.getLocale();

List supportedLocales = this.getSupportedLocales();

if (!supportedLocales.isEmpty() && !supportedLocales.contains(requestLocale)) {

Locale supportedLocale = this.findSupportedLocale(request, supportedLocales);

if (supportedLocale != null) {

return supportedLocale;

} else {

return defaultLocale != null ? defaultLocale : requestLocale;

}

} else {

return requestLocale;

}

}

}

那假如我们现在想点击链接让我们的国际化资源生效,就需要让我们自己的Locale生效!

我们去自己写一个自己的LocaleResolver,可以在链接上携带区域信息!

修改一下前端页面的跳转连接:

中文

English

我们去写一个处理的组件类!

package com.kuang.component;

import org.springframework.util.StringUtils;

import org.springframework.web.servlet.LocaleResolver;

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.getDefault(); // 如果没有获取到就使用系统默认的

//如果请求链接不为空

if (!StringUtils.isEmpty(language)){

//分割请求参数

String[] split = language.split(“_”);

//国家,地区

locale = new Locale(split[0],split[1]);

}

return locale;

}

@Override

public void setLocale(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Locale locale) {

}

}

为了让我们的区域化信息能够生效,我们需要再配置一下这个组件!在我们自己的MvcConofig下添加bean;

@Bean

public LocaleResolver localeResolver(){

return new MyLocaleResolver();

}

我们重启项目,来访问一下,发现点击按钮可以实现成功切换!搞定收工!

注意点

在这里插入图片描述

4、登录+拦截器


4.1、登录

禁用模板缓存

说明:页面存在缓存,所以我们需要禁用模板引擎的缓存

#禁用模板缓存

spring.thymeleaf.cache=false

模板引擎修改后,想要实时生效!页面修改完毕后,IDEA小技巧 : Ctrl + F9 重新编译!即可生效!

登录

我们这里就先不连接数据库了,输入任意用户名都可以登录成功!

1、我们把登录页面的表单提交地址写一个controller!

//这里面的所有表单标签都需要加上一个name属性

2、去编写对应的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 “redirect:/main.html”;

}

else{

//告诉用户,你登录失败

model.addAttribute(“msg”,“用户名或者密码错误!”);

return “index”;

}

}

}

OK ,测试登录成功!

在这里插入图片描述

3、登录失败的话,我们需要将后台信息输出到前台,可以在首页标题下面加上判断

重启登录失败测试:

在这里插入图片描述

优化,登录成功后,由于是转发,链接不变,我们可以重定向到首页!

4、我们再添加一个视图控制映射,在我们的自己的MyMvcConfifig中:

registry.addViewController(“/main.html”).setViewName(“dashboard”);

5、将 Controller 的代码改为重定向;

//登录成功!防止表单重复提交,我们重定向

return “redirect:/main.html”;

重启测试,重定向成功!后台主页正常显示!

4.2、登录拦截器

但是又发现新的问题,我们可以直接登录到后台主页,不用登录也可以实现!怎么处理这个问题呢?我

们可以使用拦截器机制,实现登录检查!

1、在LoginController添加serssion

session.setAttribute(“loginUser”,username);

2、自定义一个拦截器:

//自定义拦截器

public class LoginHandlerInterceptor implements HandlerInterceptor {

@Override

public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {

//获取 loginUser 信息进行判断

Object user = request.getSession().getAttribute(“loginUser”);

if(user == null){//未登录,返回登录页面

request.setAttribute(“msg”,“没有权限,请先登录”);

request.getRequestDispatcher(“/index.html”).forward(request,response);

return false;

}else{

//登录,放行

return true;

}

}

}

3、然后将拦截器注册到我们的SpringMVC配置类当中!

@Override

public void addInterceptors(InterceptorRegistry registry) {

// 注册拦截器,及拦截请求和要剔除哪些请求!

// 我们还需要过滤静态资源文件,否则样式显示不出来

registry.addInterceptor(new LoginHandlerInterceptor())

.addPathPatterns(“/**”)

.excludePathPatterns(“/index.html”,“/user/login”,“/”,“/css/*”,“/img/“,”/js/”);

}

4、我们然后在后台主页,获取用户登录的信息

[[ s e s s i o n . l o g i n U s e r ] ] < ! − − {session.loginUser}]] <!-- session.loginUser]]<!取EL表达式–>

然后我们登录测试拦截!完美!

5、展示员工列表


5.1、员工列表页面跳转

我们在主页点击Customers,就显示列表页面;我们去修改下

1、将首页的侧边栏Customers改为员工管理

2、a链接添加请求

员工管理

3、将list放在emp文件夹下

4、编写处理请求的controller

//员工列表

@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”;

}

}

我们启动项目,测试一下看是否能够跳转,测试OK!我们只需要将数据渲染进去即可!

但是发现了一个问题,侧边栏和顶部都相同,我们是不是应该将它抽取出来呢?

5.2、Thymeleaf公共页面元素抽取

步骤:

1、抽取公共片段 th:fragment 定义模板名

2、引入公共片段 th:insert 插入模板名

实现:

1、我们来抽取一下,使用list列表做演示!我们要抽取头部nav标签,我们在dashboard中将nav部分定

义一个模板名;

[[ s e s s i o n . l o g i n U s e r ] ] < / a > < ! − − {session.loginUser}]]</a> <!-- session.loginUser]]</a><!取EL表达式–>

  • 注销

    2、然后我们在list页面中去引入,可以删掉原来的nav

    3、启动再次测试,可以看到已经成功加载过来了!

    说明:

    除了使用insert插入,还可以使用replace替换,或者include包含,三种方式会有一些小区别,可以见名

    知义;

    我们使用replace替换,可以解决div多余的问题,可以查看thymeleaf的文档学习

    侧边栏也是同理,当做练手,可以也同步一下!

    定义模板:

    然后我们在list页面中去引入:

    启动再试试,看效果!

    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-MYb7uR0O-1620304585041)(%E5%91%98%E5%B7%A5%E7%AE%A1%E7%90%86%E7%B3%BB%E7%BB%9F.assets/image-20210504080516865.png)]

    我们发现一个小问题,侧边栏激活的问题,它总是激活第一个;按理来说,这应该是动态的才对!

    为了重用更清晰,我们建立一个commons文件夹,专门存放公共页面;

    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-oOhXpYuM-1620304585042)(%E5%91%98%E5%B7%A5%E7%AE%A1%E7%90%86%E7%B3%BB%E7%BB%9F.assets/image-20210504080721577.png)]

    我们去页面中引入一下

    我们先测试一下,保证所有的页面没有出问题!ok!

    侧边栏激活问题:

    1、将首页的超链接地址改到项目中

    2、我们在a标签中加一个判断,使用class改变标签的值;

    首页 (current)

    员工管理

    3、修改请求链接

    4、我们刷新页面,去测试一下,OK,动态激活搞定!

    5.3、员工信息页面展示

    现在我们来遍历我们的员工信息!顺便美化一些页面,增加添加,修改,删除的按钮!

    id lastName email gender department birth

    编辑

    删除

    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-3zTWfpyn-1620304585042)(%E5%91%98%E5%B7%A5%E7%AE%A1%E7%90%86%E7%B3%BB%E7%BB%9F.assets/image-20210504081556725.png)]

    OK,显示全部员工OK!

    6、添加员工实现


    6.1、表单及细节处理

    1、将添加员工信息改为超链接

    添加员工

    2、编写对应的controller

    //to员工添加页面

    @GetMapping(“/emp”)

    public String toAddPage(){

    return “emp/add”;

    }

    3、添加前端页面;复制list页面,修改即可

    bootstrap官网文档 : https://v4.bootcss.com/docs/4.0/components/forms/

    我们去可以里面找自己喜欢的样式!我这里给大家提供了编辑好的:


    添加

    4、部门信息下拉框应该选择的是我们提供的数据,所以我们要修改一下前端和后端

    Controller

    @GetMapping(“/emp”)

    public String toAddPage(Model model){

    //查询所有的部门信息

    Collection departments = departmentDao.getDepartments();

    model.addAttribute(“departments”,departments);

    return “emp/add”;

    }

    前端

    OK,修改了controller,重启项目测试!

    6.2、具体添加功能

    1、修改add页面form表单提交地址和方式

    1

    2、编写controller;

    //员工添加功能

    //接收前端传递的参数,自动封装成为对象[要求前端传递的参数名,和属性名一致]

    @PostMapping (“/emp”)

    public String addEmp(Employee employee){

    //保存员工的信息

    System.out.println(employee);

    employeeDao.save(employee);

    // 回到员工列表页面,可以使用redirect或者forward,就不会被视图解析器解析

    return “redirect:/emps”;

    }

    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-b6fVRToh-1620304585042)(%E5%91%98%E5%B7%A5%E7%AE%A1%E7%90%86%E7%B3%BB%E7%BB%9F.assets/image-20210504161017922.png)]

    回忆:重定向和转发以及 /的问题?

    时间格式问题

    生日我们提交的是一个日期 , 我们第一次使用的 / 正常提交成功了,后面使用 - 就错误了,所以这里面

    应该存在一个日期格式化的问题;

    SpringMVC会将页面提交的值转换为指定的类型,默认日期是按照 / 的方式提交 ; 比如将2019/01/01

    转换为一个date对象。

    那思考一个问题?我们能不能修改这个默认的格式呢?

    这个在配置类中,所以我们可以自定义的去修改这个时间格式化问题,我们在我们的配置文件中修改一

    下;

    spring.mvc.date-format=yyyy-MM-dd

    这样的话,我们现在就支持 - 的格式了,但是又不支持 / 了 , 2333吧

    测试OK!

    7、修改员工信息


    逻辑分析:

    我们要实现员工修改功能,需要实现两步;

    1、点击修改按钮,去到编辑页面,我们可以直接使用添加员工的页面实现

    2、显示原数据,修改完毕后跳回列表页面!

    实现

    1、我们去实现一下,首先修改跳转链接的位置;

    编辑

    2、编写对应的controller

    //员工修改页面

    @GetMapping(“/emp/{id}”)

    public String toUpdateEmp(@PathVariable(“id”) Integer id,Model model){

    Employee employee = employeeDao.getEmployeeById(id);

    model.addAttribute(“emp”,employee);

    //查询所有的部门信息

    Collection departments = departmentDao.getDepartments();

    model.addAttribute(“departments”,departments);

    return “emp/update”;

    }

    3、我们需要在这里将add页面复制一份,改为update页面;需要修改页面,将我们后台查询数据回显

    总结

    大型分布式系统犹如一个生命,系统中各个服务犹如骨骼,其中的数据犹如血液,而Kafka犹如经络,串联整个系统。这份Kafka源码笔记通过大量的设计图展示、代码分析、示例分享,把Kafka的实现脉络展示在读者面前,帮助读者更好地研读Kafka代码。

    麻烦帮忙转发一下这篇文章+关注我

    就这一次!拼多多内部架构师培训Kafka源码笔记(现已绝版)

    本文已被CODING开源项目:【一线大厂Java面试题解析+核心总结学习笔记+最新讲解视频+实战项目源码】收录

    需要这份系统化的资料的朋友,可以点击这里获取

    7、修改员工信息


    逻辑分析:

    我们要实现员工修改功能,需要实现两步;

    1、点击修改按钮,去到编辑页面,我们可以直接使用添加员工的页面实现

    2、显示原数据,修改完毕后跳回列表页面!

    实现

    1、我们去实现一下,首先修改跳转链接的位置;

    编辑

    2、编写对应的controller

    //员工修改页面

    @GetMapping(“/emp/{id}”)

    public String toUpdateEmp(@PathVariable(“id”) Integer id,Model model){

    Employee employee = employeeDao.getEmployeeById(id);

    model.addAttribute(“emp”,employee);

    //查询所有的部门信息

    Collection departments = departmentDao.getDepartments();

    model.addAttribute(“departments”,departments);

    return “emp/update”;

    }

    3、我们需要在这里将add页面复制一份,改为update页面;需要修改页面,将我们后台查询数据回显

    总结

    大型分布式系统犹如一个生命,系统中各个服务犹如骨骼,其中的数据犹如血液,而Kafka犹如经络,串联整个系统。这份Kafka源码笔记通过大量的设计图展示、代码分析、示例分享,把Kafka的实现脉络展示在读者面前,帮助读者更好地研读Kafka代码。

    麻烦帮忙转发一下这篇文章+关注我

    [外链图片转存中…(img-nPIw8L53-1715694218777)]

    本文已被CODING开源项目:【一线大厂Java面试题解析+核心总结学习笔记+最新讲解视频+实战项目源码】收录

    需要这份系统化的资料的朋友,可以点击这里获取

  • 10
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值