SpringBoot(四)SpringBootWeb开发(国际化员工信息管理系统)

一:导入模板引擎

在pom.xml文件中导入Thymeleaf依赖:

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-thymeleaf</artifactId>
</dependency>

Thymeleaf的介绍、具体功能、拥有哪些方法、怎么接管前端可以参考官方文档
https://www.thymeleaf.org/doc/tutorials/3.0/usingthymeleaf.html#using-texts

二:开发注意

  1. 建立  Spring Initializr  项目,参考以前发布的文档
  2. 这个项目会自动生成  resources  文件夹
  3. 在这个文件夹下存在  static、templates  两个文件夹
  4. 我们所有的静态资源都要放在  static  包下,例:css、js (JavaScript)、img (图片)、fonts (字体)等静态资源,因为调取静态资源时,SpringBoot自动以static为父级,直接到它下面寻找对应的静态资源,引入路径:../css/xxx.css
  5. 网页( .html)文件放在  templates  文件夹下,因为使用了Thymeleaf接管前端,SpringBoot会自动到  templates  中寻找对应的网页
  6. 配置properties文件
    #配置文件的真实位置
    spring:
      messages:
        basename: i18n.login
    #关闭模板引擎的缓存
      thymeleaf:
        cache: false
      mvc:
        format:
          date: yyyy-MM-dd

    国际化文件位置、关闭缓存、自定义时间日期输入与显示格式

查看静态资源:

  1. 查看添加的webjars包的源码:http://localhost:8080/webjars/
  2. 查看添加到static下的静态资源:http://localhost:8080/img/xxx.img

扩展:

        我们只能在static目录下放静态资源吗?不,可以放在其他地方,我们可以进到源码里看,看它支持那些文件夹,对路径的定义是什么样的,怎么创建文件夹才会被识别到,优先级的关系是什么样的。(优先级:resources>static(默认)>public)

三:项目开发

注意:所有页面的静态资源都需要使用thymeleaf进行接管!

(一)准备

  1. html文件放在  templates  文件夹下
  2. 所有静态资源(js、css、img等)放在static下

(二)首页实现

        1. 在  templates  下新建  index.html  文件

        index.html:

<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
    <meta charset="UTF-8">
    <title>index</title>
    <link rel="stylesheet" href="/webjars/bootstrap/4.1.0/css/bootstrap.min.css">
</head>
<body>
<div style="width: 10%; position: absolute;top: 30%;left: 45%">
    <form th:action="@{/user/login}">
        <p style="color: red" th:if="${not #strings.isEmpty(msg)}" th:text="${msg}"></p>
        <a th:text="#{login.user}">用户名:</a>:
        <input type="text" name="username">
        <a th:text="#{login.passWord}">密码:</a>
        <input type="password" name="password" >
        <button type="submit" th:text="#{login.enter}" style="width:100px;height:40px;">
            登录
        </button>
    </form>
    <a th:href="@{/index.html(a='zh_CN')}">中文</a>
    <a th:href="@{/index.html(a='en_US')}">英文</a>
</div>
</body>
</html>

        2. 实现网页跳转,有两种方法

                (1) controller层实现(不推荐)

@Controller
public class MyWebController{
    @RequestMapping("/index")
    public String index(){
        return "index";
    }
}

                (2)与DemoApplication同级目录下新建config包,自定义MyWebMvcConfig继承WebMvcConfigurer,重写addViewControllers方法

@Configuration
public class MyWebMvcConfic implements WebMvcConfigurer {
    @Override
    public void addViewControllers(ViewControllerRegistry registry) {
        //变量名称.addViewController("地址信息").setViewName("跳转的页面");      
        registry.addViewController("/").setViewName("index");
        //设置多个路径  
        registry.addViewController("/index.html").setViewName("index");
        registry.addViewController("/main.html").setViewName("dashboard");
    }

}

(三)国际化(添加与否纯凭个人喜好与公司要求)

        1. resources包下新建i18n包,包中新建文件如图所示:

SpringBoot(四)SpringBootWeb开发(国际化员工信息管理系统)

 

#login内为默认显示
login.tip=你好

#en_US为英语
login.tip=hello

#zh_CN为中文
login.tip=你好

        2. 配置文件中配置属性如下:

spring:
  messages:
    basename: i18n.login

        3. config包下新建MyLocalResolver.class,重写resolveLocale方法、setLocale方法

package com.demo.config;

import org.springframework.context.annotation.Configuration;
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;

@Configuration
public class MyLocalResolver implements LocaleResolver {
    //国际化
    @Override
    public Locale resolveLocale(HttpServletRequest request) {
        //获取请求中的语言参数
        String language = request.getParameter("a");
        //如果参数没有就使用系统默认
        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 request, HttpServletResponse response, Locale locale) { }
}

        4. 将重写后的configration配置到springboot成为Bean组件,在MyWebMvcConfig下配置

@Configuration
public class MyWebMvcConfic implements WebMvcConfigurer {
    //自定义国际化组件
    @Bean
    public LocaleResolver localeResolver(){
        return new MyLocalResolver();
    }
}

        5. 在index页面添加如下代码,即可实现中英文切换

 SpringBoot(四)SpringBootWeb开发(国际化员工信息管理系统)

        6. 如果想实现其他国家的语言切换,可以添加对应语言的login_xx_XX.properties,这个格式是固定的,xx_XX为语言种类

        7. 注意:需要配置i18n文件,自定义组件LocalResolver,将组件配置到SpringBoot中

(四)实现登录功能+拦截器

1.登录功能

        (1) 定义index登录页面,,添加账户名、密码输入框,添加提交按钮

<div style="width: 10%; position: absolute;top: 30%;left: 45%">
    <form th:action="@{/user/login}">
        <p style="color: red" th:if="${not #strings.isEmpty(msg)}" th:text="${msg}"></p>
        <a th:text="#{login.user}">用户名:</a>:
        <input type="text" name="username">
        <a th:text="#{login.passWord}">密码:</a>
        <input type="password" name="password" >
        <button type="submit" th:text="#{login.enter}" style="width:100px;height:40px;">
            登录
        </button>
    </form>
    <a th:href="@{/index.html(a='zh_CN')}">中文</a>
    <a th:href="@{/index.html(a='en_US')}">英文</a>
</div>

        (2) 在MyWebMvcConfig中重写拦截器方法

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

        (3) 对用户登录的信息进行验证

                1.  添加LoginController

                2.  实现登录验证

@RequestMapping("/user/login")
    public String login(@RequestParam("username") String username,
                        @RequestParam("password") String password,
                        Model model,
                        HttpSession session){

        //具体业务
        if (!StringUtils.isEmpty(username) && "123".equals(password)){
            session.setAttribute("loginUser",username);
            return "redirect:/main.html";
        }else {
            model.addAttribute("msg","登录失败");
            return "index";
        }
    }

        (4) 添加拦截器目的

                对用户登录的session信息进行验证

          防止浏览器端绕过登录,直接进入到应用,或者session超时后,返回到登录页面

        (5) 点击登录跳转到主页面dashboard.html页面

<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
    <meta charset="UTF-8">
    <title>dashboard</title>
    <link rel="stylesheet" href="/webjars/bootstrap/4.1.0/css/bootstrap.min.css">
</head>
<body>
<p>欢迎[[${session.loginUser}]]</p>
<a th:href="@{/index.html}">首页</a>
<a th:href="@{/emps}">员工管理</a>
<a th:href="@{/user/logout}">注销</a>
</body>
</html>

        (6) MyWebMvcConfic实现跳转

@Configuration
public class MyWebMvcConfic implements WebMvcConfigurer {
    @Override
    public void addViewControllers(ViewControllerRegistry registry) {
        registry.addViewController("/").setViewName("index");
        registry.addViewController("/index.html").setViewName("index");
        registry.addViewController("/main.html").setViewName("dashboard");
    }

}

(五)员工列表CRUD

        一:查询

        (1)伪造数据库员工与部门信息

                1. 与DemoApplication同级目录新建dao与pojo包

                2. 在dao包下新建DepartmentDao、EmployeeDao两个类

                3. 在pojo包下新建Department、Employee两个类

                代码如下

                DepartmentDao:

package com.demo.dao;

import com.demo.pojo.Department;
import org.springframework.stereotype.Repository;

import java.util.Collection;
import java.util.HashMap;
import java.util.Map;

@Repository
//部门表操作
public class DepartmentDao {

    //模拟数据库数据
    private static Map<Integer, Department> departments = null;
    static {
        departments = new HashMap<Integer, Department>();//创建一个部门表

        departments.put(1,new Department(1,"教学部"));
        departments.put(2,new Department(2,"教研部"));
        departments.put(3,new Department(3,"科学部"));
        departments.put(4,new Department(4,"党委"));
        departments.put(5,new Department(5,"团委"));

    }

    //获得所有部门信息
    public Collection<Department> getDepartments(){
        return departments.values();
    }
    //通过id得到部门
    public Department getDepartmentById(Integer id){
        return departments.get(id);
    }

}

                EmployeeDao:

package com.demo.dao;

import com.demo.pojo.Department;
import com.demo.pojo.Employee;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Repository;

import java.util.Collection;
import java.util.HashMap;

@Repository
//员工表操作
public class EmployeeDao {
    //模拟数据库数据
    private static HashMap<Integer, Employee> employees = null;
    //员工有所属的部门,部门表为外表
    @Autowired
    private DepartmentDao departmentDao;

    static {
        //创建一个员工表
        employees = new HashMap<Integer,Employee>();
        employees.put(1,new Employee(1,"董文杰1","1181101901@qq.com",1,new Department(1,"教学部")));
        employees.put(2,new Employee(2,"董文杰2","1181101902@qq.com",2,new Department(2,"教研部")));
        employees.put(3,new Employee(3,"董文杰3","1181101903@qq.com",1,new Department(3,"科学部")));
        employees.put(4,new Employee(4,"董文杰4","1181101904@qq.com",1,new Department(4,"党委")));
        employees.put(5,new Employee(5,"董文杰5","1181101905@qq.com",2,new Department(5,"团委")));
    }

    //id递增
    public static Integer initId = 6;
    //增加员工
    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<Employee> getall(){
        return employees.values();
    }
    //通过id查询员工
    public Employee getEmployeeById(Integer id){
        return employees.get(id);
    }

    //删除员工
    public void delete(Integer id){
        employees.remove(id);
    }
}

                Department:

package com.demo.pojo;

import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;

//伪造数据库
//部门表
@Data
@AllArgsConstructor//有参构造
@NoArgsConstructor//无参构造
public class Department {
    private Integer id;
    private String departmentName;
}

                Employee:

package com.demo.pojo;

import lombok.Data;
import lombok.NoArgsConstructor;

import java.util.Date;

@Data
@NoArgsConstructor
public class Employee {
    private Integer id;
    private String name;
    private String email;
    private Integer gender;//1男,2女
    private Department department;
    private Date birth;

    public Employee(Integer id, String name, String email, Integer gender, Department department) {
        this.id = id;
        this.name = name;
        this.email = email;
        this.gender = gender;
        this.department = department;
        //默认创建日期
        this.birth = new Date();
    }
}

        (2) 在templates包下新建emp包,在emp包下新建list.html文件

        list.html:

<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
    <meta charset="UTF-8">
    <link rel="stylesheet" href="/webjars/bootstrap/4.1.0/css/bootstrap.min.css">
    <title>list</title>
</head>
<body>
<table class="table table-bordered table-hover">
    <a class="btn btn-sm btn-success" th:href="@{/emp}">添加员工</a>
    <thead>
        <tr>
            <th>id</th>
            <th>name</th>
            <th>email</th>
            <th>gender</th>
            <th>department</th>
            <th>birth</th>
            <th>操作</th>
        </tr>
    </thead>
    <tbody>
        <tr th:each="emp:${emps}">
            <td th:text="${emp.getId()}"></td>
            <td th:text="${emp.getName()}"></td>
            <td th:text="${emp.getEmail()}"></td>
            <td th:text="${emp.getGender()==1?'男':'女'}"></td>
            <td th:text="${emp.getDepartment().getDepartmentName()}"></td>
            <td th:text="${#dates.format(emp.getBirth(),'yyyy.MM.dd HH:mm')}"></td>
            <td>
                <a th:href="@{'/emp/'+${emp.getId()}}"><button class="btn btn-sm btn-primary">编辑</button></a>
                <a th:href="@{'/delemp/'+${emp.getId()}}"><button class="btn btn-sm btn-danger">删除</button></a>
            </td>
        </tr>
    </tbody>
</table>
</body>
</html>

        (3) 前往controller层新建EmployeeController控制类

        EmployeeController:

@Autowired
    EmployeeDao emploeeDao;
    @Autowired
    DepartmentDao departmentDao;
    @RequestMapping("/emps")
    public String list(Model model){
        Collection<Employee> employees = emploeeDao.getall();
        model.addAttribute("emps",employees);
        return "emp/list";
    }

        二:添加

        在查询列表list页面添加 新增 按钮

        (1) emp包下新建add.html

        add.html:

<!DOCTYPE html>
<html lang="en"  xmlns:th="http://www.thymeleaf.org">
<head>
    <meta charset="UTF-8">
    <title>add</title>
    <link rel="stylesheet" href="/webjars/bootstrap/4.1.0/css/bootstrap.min.css">
</head>
<body>
<form class="form-horizontal" th:action="@{/emp}" method="post" style="position: absolute;left: 5%;width: 90%">
    <div class="form-group">
        <label for="name" class="col-sm-2 control-label">Name</label>
        <div class="col-sm-10">
            <input type="text" class="form-control" name="name" id="name" placeholder="name">
        </div>
    </div>

    <div class="form-group">
        <label for="email" class="col-sm-2 control-label">Email</label>
        <div class="col-sm-10">
            <input type="text" class="form-control" name="email" id="email" placeholder="email">
        </div>
    </div>

    <div class="form-group">
        <label for="birth" class="col-sm-2 control-label">Birth</label>
        <div class="col-sm-10">
            <input type="text" class="form-control" name="birth" id="birth" placeholder="birth">
        </div>
    </div>

    <div class="form-group">
        <label class="col-sm-2 control-label">Gender</label><br/>
        <div class="form-check form-check-inline">
            <input type="radio" class="form-check-input" name="gender" value="1">
            <label class="form-check-label">男</label>
        </div>
        <div class="form-check form-check-inline">
            <input type="radio" class="form-check-input" name="gender" value="2">
            <label class="form-check-label">女</label>
        </div>
    </div>

    <div class="form-group">
        <label class="col-sm-2 control-label">Department</label>
        <!--我们在controller接收的是一个Employee,所以我们需要提交的是其中的一个属性-->
        <select class="form-control" name="department.id">
            <option th:each="dept:${departments}" th:text="${dept.getDepartmentName()}" th:value="${dept.getId()}">教学部</option>
        </select>
    </div>

    <div class="form-group">
        <div class="col-sm-offset-2 col-sm-10">
            <button type="submit" class="btn btn-default">添加</button>
        </div>
    </div>
</form>
</body>
</html>

        (2) 点击新增按钮,在EmployeeController实现页面跳转

@GetMapping("/emp")
    public String toAddPage(Model model){
        //查询部门信息
        Collection<Department> departments = departmentDao.getDepartments();
        model.addAttribute("departments",departments);
        return "/emp/add";
    }

        (3) 填写新增员工信息后点击提交,controller层EmployeeController实现添加操作

        EmployeeController:

@PostMapping("/emp")
    public String addEmp(Employee employee){
        //添加的操作   forward
        //调用底层业务方法保存员工信息
        emploeeDao.save(employee);
        return "redirect:/emps";
    }

注意:跳转时都是"/emp",为什么会分成两个方法,因为注解不一样,PostMapping处理method为post的请求,而Get处理普通请求;

        三:修改

        在员工信息后添加 修改 按钮

        (1) emp包下新建update.html

        update.html:

<!DOCTYPE html>
<html lang="en"  xmlns:th="http://www.thymeleaf.org">
<head>
  <meta charset="UTF-8">
  <title>update</title>
  <link rel="stylesheet" href="/webjars/bootstrap/4.1.0/css/bootstrap.min.css">
</head>
<body>
<form class="form-horizontal" th:action="@{/updateEmp}" method="post" style="position: absolute;left: 5%;width: 90%">
  <input type="hidden" name="id" th:value="${emp.getId()}">
  <div class="form-group">
    <label for="name" class="col-sm-2 control-label">Name</label>
    <div class="col-sm-10">
      <input th:value="${emp.getName()}" type="text" class="form-control" name="name" id="name" placeholder="name">
    </div>
  </div>

  <div class="form-group">
    <label for="email" class="col-sm-2 control-label">Email</label>
    <div class="col-sm-10">
      <input th:value="${emp.getEmail()}" type="text" class="form-control" name="email" id="email" placeholder="email">
    </div>
  </div>

  <div class="form-group">
    <label for="birth" class="col-sm-2 control-label">Birth</label>
    <div class="col-sm-10">
      <input th:value="${#dates.format(emp.getBirth(),'yyyy-MM-dd HH:mm')}" type="text" class="form-control" name="birth" id="birth" placeholder="birth">
    </div>
  </div>

  <div class="form-group">
    <label class="col-sm-2 control-label">Gender</label><br/>
    <div class="form-check form-check-inline">
      <input th:checked="${emp.getGender()==1}" type="radio" class="form-check-input" name="gender" value="1">
      <label class="form-check-label">男</label>
    </div>
    <div class="form-check form-check-inline">
      <input th:checked="${emp.getGender()==2}" type="radio" class="form-check-input" name="gender" value="2">
      <label class="form-check-label">女</label>
    </div>
  </div>

  <div class="form-group">
    <label class="col-sm-2 control-label">Department</label>
    <!--我们在controller接收的是一个Employee,所以我们需要提交的是其中的一个属性-->
    <select class="form-control" name="department.id">
      <option th:selected="${dept.getId()==emp.getDepartment().getId()}" th:each="dept:${departments}"
              th:text="${dept.getDepartmentName()}" th:value="${dept.getId()}">教学部</option>
    </select>
  </div>

  <div class="form-group">
    <div class="col-sm-offset-2 col-sm-10">
      <button type="submit" class="btn btn-default">确认修改</button>
    </div>
  </div>
</form>
</body>
</html>

        (2) 点击修改按钮,在EmployeeController实现页面跳转

@GetMapping("/emp/{id}")
    public String toUpdateEmp(@PathVariable("id") Integer id, Model model){
        Employee employee = emploeeDao.getEmployeeById(id);
        model.addAttribute("emp",employee);
        //查询部门信息
        Collection<Department> departments = departmentDao.getDepartments();
        model.addAttribute("departments",departments);
        return "/emp/update";
    }

        (3) 修改员工信息后点击提交,controller层EmployeeController实现修改操作

        EmployeeController:

//员工信息修改
    @RequestMapping("/updateEmp")
    public String updateEmp(Employee employee){
        emploeeDao.save(employee);
        return "redirect:/emps";
    }

        三:删除

        在员工信息后添加 删除 按钮

        (1) 点击删除按钮,在EmployeeController实现功能

//删除员工
    @GetMapping("/delemp/{id}")
    public String delEmp(@PathVariable("id") Integer id){
        emploeeDao.delete(id);
        return "redirect:/emps";
    }

注意:删除与添加和修改不一样,删除直接依据当前员工id查询即可删除。

完整目录与代码结构如下

SpringBoot(四)SpringBootWeb开发(国际化员工信息管理系统)

LoginHandlerInterceptor

SpringBoot(四)SpringBootWeb开发(国际化员工信息管理系统)

MyLocalResolver

SpringBoot(四)SpringBootWeb开发(国际化员工信息管理系统)

MyWebMvcConfic

SpringBoot(四)SpringBootWeb开发(国际化员工信息管理系统)

 EmployeeController   {{{

SpringBoot(四)SpringBootWeb开发(国际化员工信息管理系统)

SpringBoot(四)SpringBootWeb开发(国际化员工信息管理系统)

SpringBoot(四)SpringBootWeb开发(国际化员工信息管理系统)

 }}}

LoginController

SpringBoot(四)SpringBootWeb开发(国际化员工信息管理系统)

 DepartmentDaoSpringBoot(四)SpringBootWeb开发(国际化员工信息管理系统)

 EmployeeDao  {{{SpringBoot(四)SpringBootWeb开发(国际化员工信息管理系统)

SpringBoot(四)SpringBootWeb开发(国际化员工信息管理系统)

 }}}

Department

SpringBoot(四)SpringBootWeb开发(国际化员工信息管理系统)

 EmployeeSpringBoot(四)SpringBootWeb开发(国际化员工信息管理系统)

 login.propertiesSpringBoot(四)SpringBootWeb开发(国际化员工信息管理系统)

所有的java代码都已截图,还有兴趣去添加没有找到网页(404)或者服务器错误(500)的小伙伴可以借鉴一下我写的跳转的代码,自定义html文件,实现404或者500后的提示。 

愿收获更好的自己!

上一篇:【免费下载】全套最新 016SpringBoot 视频教程+教学资料+学习课件+源代码+软件开发工具


下一篇:java分别发送post请求application/x-www-form-urlencoded和application/json类型数据