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

狂神-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
    
  • 重新定义了项目的访问路径,之后重新访问,并查看源代码

    在这里插入图片描述

9.3页面国际化

  • 有的时候,我们的网站会去涉及中英文甚至多语言的切换,这时候我们就需要学习国际化了!
9.3.1准备工作
  • 先在IDEA中统一设置properties的编码问题!

在这里插入图片描述

9.3.2配置文件编写
  • 编写国际化配置文件,抽取页面需要显示的国际化页面消息。我们可以去登录页面查看一下,哪些内容我们需要编写国际化的配置!

    • 1、我们在resources资源文件下新建一个i18n目录,存放国际化配置文件

    • 2、建立一个login.properties文件,还有一个login_zh_CN.properties;发现IDEA自动识别了我们要做国际化操作;文件夹变了!

    在这里插入图片描述

    • 3、我们可以在这上面去新建一个文件; 弹出如下页面:我们再添加一个英文的;

      在这里插入图片描述

      在这里插入图片描述
      在这里插入图片描述

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

      在这里插入图片描述

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

        在这里插入图片描述

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

        在这里插入图片描述

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

      在这里插入图片描述

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

        # 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取值操作为:#{…}。我们去页面测试下:

    在这里插入图片描述

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

    在这里插入图片描述

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

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文档来学习,在这官网如果进不去,可以参考https://blog.csdn.net/liuminglei1987/article/details/106692004 ,这是个一篇Thymeleaf参考手册的博客,感谢博主总结!

  • 要知道thymeleaf ,获取普通变量值 . . . ; 选 择 表 达 式 ∗ . . . : 和 {...} ; 选择表达式 *{...}:和 ......{}在功能上是一样;获取国际化内容 #{…}
    ;定义URL @{…} ; 片段引用表达式 ~{…}

  • 抽取 重复的前端代码: 在第一层标签中加上 th:fragment=“templatename” ,之后在需要这段代码的位置使用属性 th:insertth:replace 属性,表达式是 “~{templatename::fragmentname}”,如图

    在这里插入图片描述

  • 如果要传递参数,可以直接使用() 传参,此处做了一个选中高亮显示

    在这里插入图片描述

  • 列表循环展示

    <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这样的错误代码命名的,当出现错误时,会自动的寻找对应的错误显示页面
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

悬浮海

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值