1. 程式人生 > 其它 >SpringBoot 員工管理系統①

SpringBoot 員工管理系統①

準備工作、首頁實現、國際化

SpringBoot 員工管理系統①

好久沒寫 SpringBoot 了···發現還是寫演算法題有意思,寫完就溜不會還能看看答案。不過最後還是得把這個小小專案寫一下。

1. 準備工作

首先建立個 SpringBoot-04-EMS 專案,不想用之前的專案了,切割一下。建立時新增 Spring Web、Thymeleaf、Lombok 的依賴。

建立完後匯入靜態資原始檔,模板放到 templates 目錄下,js、css、img 放到 statics 目錄下。這裡突然發現 Maven 的路徑又被 IDEA 重置了,怪不得匯入了好久。

靜態資源匯入完後,本來應該到資料庫的配置階段了,不過現在先不用資料庫,偽造資料庫來進行使用。在 com.qiyuan.entity 包下建立部門類 Department

,充當部門表

@Data
@AllArgsConstructor
@NoArgsConstructor
@ToString
public class Department {
    private Integer id;
    private String departmentName;
}

再建立員工類 Employee,充當員工表

@Data
@NoArgsConstructor
@ToString
public class Employee {
    private Integer id;
    private String name;
    private String email;
    private Integer gender; // 0 女 1 男
    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();
    }
}

這樣兩個實體類就建立完了,它們應該對應資料庫中的兩張表。

現在編寫 Dao 類(若使用 MyBatis 就是 Mapper 類了),在 com.qiyuan.dao 包下建立 DepartmentDao 類,在其中用 Map 模擬資料,同時使用了 @Repository 註解將這個類交給了 Spring 管理

@Repository
public class DepartmentDao {
    // 用 Map 模擬資料庫中的資料,key 就相當於主鍵了

    private static Map<Integer, Department> departmentMap = null;

    // 靜態程式碼段,類初始化時就載入
    static {
        departmentMap = new HashMap<>();
        departmentMap.put(101,new Department(101,"教學部門"));
        departmentMap.put(102,new Department(102,"市場部門"));
        departmentMap.put(103,new Department(103,"研發部門"));
        departmentMap.put(104,new Department(104,"運營部門"));
        departmentMap.put(105,new Department(105,"後勤部門"));
    }

    // 查詢所有部門資訊
    public Collection<Department> getDepartments(){
        return departmentMap.values();
    }

    // 通過 id 查詢部門
    public Department getDepartmentById(Integer id){
        return departmentMap.get(id);
    }
}

再建立 EmployeeDao 類,模擬對員工表的操作,同樣以 Map 模擬資料,同時引入了 DepartmentDao 物件,以獲取其中的資料,這一步由 Spring 的自動裝配實現!

@Repository
public class EmployeeDao {
    // 用 Map 模擬資料庫中的資料,key 就相當於主鍵了
    private static Map<Integer, Employee> employeeMap = null;

    // 自動裝配
    @Autowired
    private static DepartmentDao departmentDao;

    // 靜態程式碼段,類初始化時就載入
    static {
        employeeMap = new HashMap<>();
        employeeMap.put(1001,new Employee(1001,"A","A@email",0,new Department(101,"教學部門")));
        employeeMap.put(1002,new Employee(1002,"B","B@email",1,new Department(102,"市場部門")));
        employeeMap.put(1003,new Employee(1003,"C","C@email",0,new Department(103,"研發部門")));
        employeeMap.put(1004,new Employee(1004,"D","D@email",1,new Department(104,"運營部門")));
        employeeMap.put(1005,new Employee(1005,"E","E@email",0,new Department(105,"後勤部門")));
    }

    // 主鍵自增
    private static Integer initId = 1006;

    // 增加員工
    public void addEmployee(Employee employee){
        if(employee.getId()==null)
            employee.setId(initId++);
        employee.setDepartment(departmentDao.getDepartmentById(employee.getDepartment().getId()));
        employeeMap.put(employee.getId(),employee);
    }

    // 查詢所有員工
    public Collection<Employee> getEmployees(){
        return employeeMap.values();
    }

    // 根據 id 查詢員工
    public Employee getEmployeeById(Integer id){
        return employeeMap.get(id);
    }

    // 刪除員工
    public void deleteEmployee(Integer id){
        employeeMap.remove(id);
    }
}

本來想引用 DepartmentDao 中的部門的資料的,但這樣執行時會報空指標異常,所以就改成直接建立部門物件的方式了。初步猜測可能是類載入時先於 Spring 的自動裝配,導致 departmentDao 指標異常。

至此資料庫和靜態資源就算準備完成了!進入下一步!

2. 首頁實現

配置首頁就是讓專案開啟時的路徑 / 設定一個檢視,可以通過一個控制器來實現,在 com.qiyuan.controller 包下建立 IndexController

@Controller
public class IndexController {
    @RequestMapping({"/","/index.html"})
    public String index(){
        return "index";
    }
}

這樣這個控制器就會將 //index.html 的請求返回 index 檢視,經過檢視解析器(此處應該是 Thymeleaf 的檢視解析器)解析為 index.html 頁面。

不過上一節(說是上一節,其實是好久前= =)中學習了 MVC 的配置,我們可以通過配置類自己配置一些 MVC 的操作,首先在 com.qiyuan.config 包下建立 MyMvcConfig 類,實現 WebMvcConfigurer 介面

@Configuration
public class MyMvcConfig implements WebMvcConfigurer {
    
}

然後在其中新增檢視解析器,解析 //index.html 請求

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

這兩種方式都能處理請求,因為此處是首頁設定,所以採用第二種比較好,第一種的控制器也可以刪掉了,不用為首頁單獨建立一個控制器。

不過這時候開啟首頁發現載入不出 css 樣式(其實是路徑的問題),修改路徑的同時順便用 Thymeleaf 的語法修改一下匯入的模板檔案。

首先在 index.html 檔案的頭部新增名稱空間的引用

<html lang="en" xmlns:th="http://www.thymeleaf.org">

然後使用 th 名稱空間修改其中對 css 樣式和 img 圖片引用的標籤,此處連結改為了 Thymeleaf 的語法 @{}

<!-- 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">
...
<img class="mb-4" th:src="@{/img/bootstrap-solid.svg}" alt="" width="72" height="72">

修改完後首頁的顯示就一切正常了!同理,其他幾個頁面模板的 href 連結也是如此修改,使用 @{} 的好處是,如果專案具有專案路徑,則 @{} 會自動將專案路徑加到引用資源的路徑上。

此處只用修改本地檔案資源的引用,網路資源的引用就不用改了。

3. 國際化

常見的網站中,大部分都有中英文切換的功能,在繼續完善專案前,先來學習一下怎麼進行頁面的國際化。

首先在 resources 資源目錄下建立一個 i18n 的資料夾( i18n,internationalization 的縮寫),並在其中建立 login.properties 檔案,建立完這個檔案後,再建立一個 login_zh_CN.properties 的檔案,即中文的配置。

這兩個檔案都建立完後,IDEA 就會把它們合併到 Resource Bundle 'login' 中,此時在上面選擇 Add Property Files to Resource Bundle,可以看到配置檔案與國家地區的對應。再新增一個 en_US 的配置,對應英語/美國。此時 Resource Bundle 'login' 中就有三個檔案了,即預設配置,中文配置,英文配置。

此時進入 IDEA 的 Resource Bundle 視窗,新增一個 Property Key 為 login.tip,可以看到出現了三種配置檔案對應的輸入框,在其中輸入該詞條對應的內容即可!同理,新增使用者名稱、密碼、記住我、登入的中英文對照配置

這樣不同語言的內容就配置好了,該如何識別呢?這就要用到 MessageSourceAutoConfiguration 自動配置類了,這個類可以通過 spring.message 進行定製。在 application.properties 中新增配置

# 配置檔案的 真實位置
spring.messages.basename=i18n.login

然後,在要用到資訊文字的地方,使用 Thymeleaf 的 #{} 獲取資訊,但取資訊的方式在不同標籤中是不同的,如

<h1 class="h3 mb-3 font-weight-normal" th:text="#{login.tip}">Please sign in</h1>
<input type="text" class="form-control" th:placeholder="#{login.username}" required="" autofocus="">
<input type="password" class="form-control" th:placeholder="#{login.password}" required="">
<input type="checkbox" value="remember-me"> [[#{login.remember}]]
<button class="btn btn-lg btn-primary btn-block" type="submit">[[#{login.btn}]]</button>

此時再進入首頁,顯示的就是中文了,且資訊是從配置檔案中獲取的!

不過現在還沒有完成點選按鈕切換語言的功能,在瞭解如何做之前,先了解是如何做到的,在 WebMvcAutoConfiguration 類中,有解析地區的方法 localeResolver()

public LocaleResolver localeResolver() {
    // 若使用者有自己的配置,返回自己的配置
    // 否則用預設的配置 AcceptHeaderLocaleResolver
}

其中用到了 AcceptHeaderLocaleResolver 地區解析器類,這個類實現了 LocaleResolver 介面,所以它就是一個地區解析器

public class AcceptHeaderLocaleResolver implements LocaleResolver

也就是說,我們也可以自己寫一個地區解析器,只要實現這個介面就行了!

先修改前端頁面,為選擇語言的按鈕新增連結

<a class="btn btn-sm" th:href="@{/index.html(lang='zh_CN')}">中文</a>
<a class="btn btn-sm" th:href="@{/index.html(lang='en_US')}">English</a>

然後在 com.qiyuan.config 包下建立 MyLocaleResolver 類,實現 LocaleResolver介面,要求實現兩個方法,此處實現返回地區的方法 resolveLocale 即可

public class MyLocaleResolver implements LocaleResolver {
    @Override
    public Locale resolveLocale(HttpServletRequest request) {
        // 獲取請求中的語言引數
        String language = request.getParameter("lang");
        // 建立一個預設的 locale 物件,沒有設定就使用預設的
        Locale locale = Locale.getDefault();
        // 如果獲取到了 國際化語言的引數
        if(!StringUtils.isEmpty(language)){
            // 將 zh_CN 分割為語言和地區
            String[] split = language.split("_");
            // 用 語言 和 地區 引數建立 locale 物件
            locale = new Locale(split[0], split[1]);
        }
        return locale;
    }

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

    }
}

有了這個地區解析器元件後,就要把它放到 Spring 中,在 MyMvcConfig 配置類中把它註冊為 Bean

@Configuration
public class MyMvcConfig implements WebMvcConfigurer {
    
    ...

    // 讓該元件生效!
    @Bean
    public LocaleResolver localeResolver(){
        return new MyLocaleResolver();
    }
}

這樣國際化就完成了,可以通過按鈕切換頁面的語言!

步驟小結

  1. 配置 i18n 檔案對應不同語言的文字
  2. 前端頁面獲取文字中的資訊
  3. 實現一個地區解析器元件 LocaleResolver
  4. 將該元件註冊到 Spring 中(@Bean)

目前算是開了個頭,後面還要繼續完善這個專案!