​狂神-SpringBoot笔记目录​


文章目录


九、一个简单的员工管理系统

  • 这个系统不是完整的,它只是为了看一下,使用SpringBoot开发,我们要进行哪些操作!

9.1准备工作

  • 导入lombok 依赖
  • Lombok项目是一个Java库,它会自动插入编辑器和构建工具中,Lombok提供了一组有用的注释,用来消除Java类中的大量样板代码。仅五个字符(@Data)就可以替换数百行代码从而产生干净,简洁且易于维护的Java类。用在实体类中,用注解生成构造方法,get/set,等方法
  • @Data: 注解在类,生成setter/getter、equals、canEqual、hashCode、toString方法,如为final属性,则不会为该属性生成setter方法。
  • 导入lombok需要安装插件:可以参考这个文章:https://www.freesion.com/article/5093806462/
<!--lombok-->
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
<version>1.18.2</version>
</dependency>
  • 之后编写实体类Department ,Employee,以及对应的dao ,DepartmentDao,EmployeeDao

9.2首页实现

  • 首页配置:注意点:所有页面的静态资源导入都需要使用Thymeleaf接管,步骤为导入命名空间,之后将静态资源的链接变为 th:href="@{/css/bootstrap.min.css}" ,这个地方的链接开头一定要是/ ,如果我们在application.properties 配置文件中,重新定义了项目的访问路径,springboot会帮我们在链接前加上新的访问路径
  • index.html 看第2,10,12行,
<!DOCTYPE html>
<html lang="en" xml:th="http://www.thymeleaf.org" xmlns:th="http://www.w3.org/1999/xhtml">
<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">...</body>
</html>
  • application.properties
#关闭模板引擎缓存
spring.thymeleaf.cache=false

# 新的访问路径
server.servlet.context-path=/wlw
  • 重新定义了项目的访问路径,之后重新访问,并查看源代码
  • 九、【SpringBoot】一个简单的员工管理系统_springboot案例

9.3页面国际化

  • 有的时候,我们的网站会去涉及中英文甚至多语言的切换,这时候我们就需要学习国际化了!

9.3.1准备工作

  • 先在IDEA中统一设置properties的编码问题!

九、【SpringBoot】一个简单的员工管理系统_html_02

9.3.2配置文件编写

  • 编写国际化配置文件,抽取页面需要显示的国际化页面消息。我们可以去登录页面查看一下,哪些内容我们需要编写国际化的配置!
  • 1、我们在resources资源文件下新建一个i18n目录,存放国际化配置文件
  • 2、建立一个login.properties文件,还有一个login_zh_CN.properties;发现IDEA自动识别了我们要做国际化操作;文件夹变了!
  • 3、我们可以在这上面去新建一个文件; 弹出如下页面:我们再添加一个英文的;

    九、【SpringBoot】一个简单的员工管理系统_springboot案例_03

    九、【SpringBoot】一个简单的员工管理系统_spring_04


  • 九、【SpringBoot】一个简单的员工管理系统_springboot案例_05

  • 4、接下来,我们就来编写配置,我们可以看到idea下面有另外一个视图;

  • 九、【SpringBoot】一个简单的员工管理系统_配置文件_06

    • 这个视图我们点击 + 号就可以直接添加属性了;我们新建一个login.tip,可以看到边上有三个文件框可以输入;

      九、【SpringBoot】一个简单的员工管理系统_配置文件_07

    • 我们添加一下首页的内容!

      九、【SpringBoot】一个简单的员工管理系统_配置文件_08

    • 然后依次添加其他页面内容即可!

    九、【SpringBoot】一个简单的员工管理系统_配置文件_09

    • 然后去查看我们的配置文件;

      # login.properties

      login.password=
      login.remember=
      login.tip=
      login.username=
      loign.btn=
      #login_zh_CN.properties
      login.password=
      login.remember=
      login.tip=
      login.username=
      loign.btn=
      #login_en_US.properties
      login.password=Password
      login.remember=Remember me
      login.tip=Please sign in
      login.username=Username
      loign.btn=Sign in
      • OK,配置文件步骤搞定!

9.3.3配置文件生效探究

  • 我们去看一下SpringBoot对国际化的自动配置!这里又涉及到一个类:MessageSourceAutoConfiguration
  • 里面有一个方法,这里发现SpringBoot已经自动配置好了管理我们国际化资源文件(就是在i8n文件夹下的文件)的组件 ResourceBundleMessageSource; (这个东西是识别国际化配置信息文件里的信息,而下面的那个LocaleResolver 是判断我们是否自己写了国家化配置信息文件)
// 获取 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

9.3.4配置页面国际化值

  • 去页面获取国际化的值,查看Thymeleaf的文档,找到message取值操作为:#{…}。我们去页面测试下:
  • 九、【SpringBoot】一个简单的员工管理系统_配置文件_10

  • 我们可以去启动项目,访问一下,发现已经自动识别为中文的了!
  • 九、【SpringBoot】一个简单的员工管理系统_配置文件_11

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

9.3.5配置国际化解析

  • 在Spring中有一个国际化的Locale (区域信息对象);里面有一个叫做LocaleResolver (获取区域信息对象)的解析器!
  • 我们去我们webmvc(WebMvcAutoConfiguration.java)自动配置文件,寻找一下!看到SpringBoot默认配置:
@Bean
@ConditionalOnMissingBean
@ConditionalOnProperty(prefix = "spring.mvc", name = "locale")
public LocaleResolver localeResolver() {
// 容器中没有就自己配,有的话就用用户配置的(在application.properties配置文件中 spring.messages.basename=i18n.login 这一句就是绑定用户自己配置的国家化信息)
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 class AcceptHeaderLocaleResolver implements LocaleResolver{
...
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<Locale> 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,可以在链接上携带区域信息!修改一下前端页面的跳转连接:
<!-- 这里传入参数不需要使用 ?使用 (key=value)-->
<a class="btn btn-sm" th:href="@{/index.html(language='zh_CN')}">中文</a>
<a class="btn btn-sm" th:href="@{/index.html(language='en_US')}">English</a>
  • 我们去写一个处理的组件类!
package com.wlw.config;


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 MyLocalResolver implements LocaleResolver {

//解析请求
@Override
public Locale resolveLocale(HttpServletRequest request) {
//获取请求参数
String language = request.getParameter("language");
Locale locale = Locale.getDefault();//如果没有就使用默认的
//如果请求的链接中携带了国际化的参数,就获取,拆分
if(!StringUtils.isEmpty(language)){
String[] split = language.split("_"); //zh_CN
//国家,地区
locale = new Locale(split[0],split[1]);
}

return locale;
}

@Override
public void setLocale(HttpServletRequest request, HttpServletResponse response, Locale locale) {

}
}
  • 为了让我们的区域化信息能够生效,我们需要再配置一下这个组件!在我们自己的MvcConfig下添加bean;
//自定义的国家化组件就生效了
@Bean //注入组件
public LocaleResolver localeResolver(){
return new MyLocalResolver();
}
  • 我们重启项目,来访问一下,发现点击按钮可以实现成功切换!搞定收工!

9.3.6总结

  • 页面国家化步骤:
  • 我们需要配置i18n文件,并在application.properties配置文件中绑定,之后在对应的html中用thymeleaf获取(获取国家化信息使用#{} ,链接url是@{} ,变量${})
  • 如果我们需要在项目中进行按钮自动切换,我们需要自己定义一个组件MyLocalResolver继承LocaleResolver
  • 记得将自己写的组件配置到spring容器中,@Bean

9.4登录功能与登录拦截器

  • LoginController
package com.wlw.controller;

import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;

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","用户名或密码错误"); //返回到index的提示信息
return "index";
}
}
}
  • LoginHnadlerInterceptor
package com.wlw.config;

import org.springframework.web.servlet.HandlerInterceptor;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

public class LoginHnadlerInterceptor implements HandlerInterceptor {
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
HttpSession session = request.getSession();
//登录成功之后应有 用户的session
if(session.getAttribute("loginUser") == null){ //登录失败
request.setAttribute("msg","没有权限,请先登录!");
request.getRequestDispatcher("/index.html").forward(request,response);//转发到index.html 显示提示信息
return false;
}else { //登录成功
return true;
}
}
}
  • MyMvcConfig
package com.wlw.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;

import java.util.Locale;

//如果你想diy一些定制化的功能,只要写这个组件,然后把它交给SpringBoot,SpringBoot就会帮我们自动装配
@Configuration //这个注解表明这是扩展的SpringMVC
public class MyMvcConfig implements WebMvcConfigurer {

@Override
public void addViewControllers(ViewControllerRegistry registry) {
registry.addViewController("/").setViewName("index");
registry.addViewController("/index").setViewName("index");
registry.addViewController("/index.html").setViewName("index");
registry.addViewController("/main.html").setViewName("dashboard");

}

//自定义的国际化组件就生效了
@Bean //注入组件
public LocaleResolver localeResolver(){
return new MyLocalResolver();
}

//拦截器
@Override
public void addInterceptors(InterceptorRegistry registry) {
registry.addInterceptor(new LoginHnadlerInterceptor())
.addPathPatterns("/**")
.excludePathPatterns("/index.html","/","/user/login","/css/**","/js/**","img/**");
}
}

9.5展现员工列表

  • 这一部分主要是对前端页面的学习,学习thymeleaf的应用,主要还是要通过Thymeleaf文档来学习,在这官网如果进不去,可以参考这是个一篇Thymeleaf参考手册的博客,感谢博主总结!
  • 要知道thymeleaf ,获取普通变量值九、【SpringBoot】一个简单的员工管理系统_html_12{}在功能上是一样;获取国际化内容 #{…}
    ;定义URL @{…} ; 片段引用表达式 ~{…}
  • 抽取 重复的前端代码: 在第一层标签中加上 th:fragment=“templatename” ,之后在需要这段代码的位置使用属性th:insertth:replace 属性,表达式是 “~{templatename::fragmentname}”,如图
  • 九、【SpringBoot】一个简单的员工管理系统_spring_13

  • 如果要传递参数,可以直接使用() 传参,此处做了一个选中高亮显示
  • 九、【SpringBoot】一个简单的员工管理系统_配置文件_14

  • 列表循环展示
<table class="table table-striped table-sm">
<thead>
<tr>
<th>id</th>
<th>lastName</th>
<th>email</th>
<th>gender</th>
<th>birth</th>
<th>department</th>
<th>操作</th>
</tr>
</thead>
<tbody>
<tr th:each="emp:${emps}" >
<td th:text="${emp.getId()}"></td>
<td th:text="${emp.getLastName()}"></td>
<td th:text="${emp.getEmail()}"></td>
<td th:text="${emp.getGender()==0?'女':'男'}"></td>
<td th:text="${#dates.format(emp.getBirth(),'yyyy-MM-dd HH:mm:ss')}"></td>
<td th:text="${emp.department.getDepartmentName()}"></td>
<td>
<button class="btn btn-sm btn-primary">编辑</button>
<button class="btn btn-sm btn-danger">删除</button>
</td>
</tr>
</tbody>
</table>

9.6添加,修改与删除员工

  • 主要是一个逻辑操作,和之前的操作差不多,新东西还是thymeleaf在各个标签的用法
  • 看代码吧
  • 项目为:springboot_03_web

9.7错误处理

  • 很简单,只要在templates文件夹下建立一个error文件夹,并且里面的html文件是以404或500这样的错误代码命名的,当出现错误时,会自动的寻找对应的错误显示页面