天天看點

SpringBoot+thymeleaf實作視圖控制器,攔截器,國際化功能

  • 注意:

    1、配置視圖控制器要添加web依賴,視圖跳轉到templates包下的頁面需要添加thymeleaf依賴

    2、thymeleaf模闆引擎預設掃描templates包下的頁面,且預設字尾名為.html是以我們可以不用加字尾名。

    3、所有頁面的靜态資源度需要thymeleaf來接管:@{}。導入别人的頁面時,要引入thymeleaf模闆引擎的頭檔案(命名空間)才會在HTML頁面中加載static中的樣式,(thymeleaf預設從static包中找樣式,頁面樣式引入需要采用thymeleaf文法才能生效@{/static檔案下的路徑})

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

    4、如果樣式沒有生效可能是thymeleaf緩存的問題,需要在主配置檔案中關閉緩存spring.thymeleaf.cache = false

    5、springboot自動幫我們進行了配置,當程式出現錯誤後,會自動找到error檔案下的錯誤頁面

一、視圖控制器

1)視圖控制器:作用可以集中控制前端發送跳轉頁面的請求并返還指定視圖。(即所有直接跳轉頁面的請求都可在視圖控制器中配置)

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

配置視圖控制器我們需要帶入web依賴,實作WebMvcConfigurer接口并重寫addViewControllers()方法

SpringBoot+thymeleaf實作視圖控制器,攔截器,國際化功能
//配置mvc
@Configuration
public class MyMvcConfig implements WebMvcConfigurer {
    //配置視圖控制  我們初始化視圖
    @Override
    public void addViewControllers(ViewControllerRegistry registry) {
        registry.addViewController("/").setViewName("login"); //通路路徑時/時,跳轉到登入頁面
        registry.addViewController("/index").setViewName("index");  //通路路徑是/index時,跳轉到index首頁
        registry.addViewController("/error").setViewName("error");  //通路路徑是/error時,跳轉到error首頁
    }
           

2)視圖解析器:SpringBoot自動為Thymealf注冊了一個視圖解析器ThymealfViewResolver,并且配置了模闆(HTML)的位置,與JSP類似的字首+視圖名+字尾的風格。我們可以進到它的配置檔案(ThymeleafProperties)裡去看:thymeleaf模闆引擎預設掃描templates包下的頁面,且預設字尾名為.html是以我們可以不用加字尾名。

SpringBoot+thymeleaf實作視圖控制器,攔截器,國際化功能
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-thymeleaf</artifactId>
</dependency>
           

二、攔截器

攔截器作用:攔截器可以對請求的所有路徑進行攔截和放行。防止使用者通過位址欄直接通路頁面。

1)自定義攔截器,配置攔截規則:實作HandlerInterceptor接口重寫preHandle預處理方法,擷取session中的使用者,判斷是否登入過,有值即登入過可放行,為null即沒登入過,重定向到登入頁面。

SpringBoot+thymeleaf實作視圖控制器,攔截器,國際化功能
//自定義攔截器:實作攔截器接口,重寫預處理方法
public class MyInterceptor implements HandlerInterceptor {
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        Object user = request.getSession().getAttribute("user"); //判斷是否登入,登入後session中存有使用者 return true放行 return false 攔截
        if (user == null) {
             response.sendRedirect("/login"); //重定向到登入頁面
             return false;
        } else {
            return true;
        }
    }
}
           

2)添加攔截器:自定義了攔截器之後,還需要将攔截器添加到SpringBoot配置中,在實作了WebMvcConfigurer的類中重寫添加攔截器方法addInterceptors,攔截所有路徑并排除登入通路路徑,和一些靜态資源路徑。

SpringBoot+thymeleaf實作視圖控制器,攔截器,國際化功能
//添加攔截器
    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        registry.addInterceptor(new MyInterceptor())
                .addPathPatterns("/**") //攔截所有資源
                .excludePathPatterns("/login","/","/error","/css/*","/images/**","/js/**","/lib/**"); //不攔截資源路徑,登入路徑,靜态資源路徑
    }
           

三、theymeleaf國際化

spring boot 會根據請求頭中的 區域資訊自動的選擇語言

效果圖:

SpringBoot+thymeleaf實作視圖控制器,攔截器,國際化功能

如果将浏覽器的語言切換到英語會看到圖示效果

SpringBoot+thymeleaf實作視圖控制器,攔截器,國際化功能

在SpringBoot項目裡面做國際化,隻需要在resources/i18n路徑下建立xxx.properties、xxx_en_US.properties、xxx_zh_CN.properties即可。具體怎麼做,将在下文進行示範。

在SpringBoot中有一個messageSourceAutoConfiguration,它會自動管理國際化資源檔案。

SpringBoot+thymeleaf實作視圖控制器,攔截器,國際化功能

也就是說,我們在resources/i18n建立的國際化配置檔案字首名為message時,SpringBoot會自動加載。

SpringBoot+thymeleaf實作視圖控制器,攔截器,國際化功能

當然,我們也可以自己定義國際化檔案名稱,這裡我們将國際化配置檔案命名為login。

1、去yml配置檔案中配置國際化

spring
  messages: i18n.login
           

2、要確定檔案編碼是UTF-8,可以到idea的設定裡去設定并讓其自動轉換,Editor->File Encodings

SpringBoot+thymeleaf實作視圖控制器,攔截器,國際化功能

3、建立i18n檔案夾及3個國際化配置檔案,如圖

其中login.properties是基礎配置檔案(預設),如果你的浏覽器它是其他語言比如法語,是沒有辦法國際化的,是以它就會采用login.properties

SpringBoot+thymeleaf實作視圖控制器,攔截器,國際化功能

在idea裡隻要建立兩個國際化的配置檔案就會自動加入到Resource Bundle ‘xxx’,當然我們還是需要建立三個properties配置檔案。字尾必須按格式寫,_en_US就是英文,_zh_CN就是中文。

4、編寫國際化

我們直接點進login.properties,可以看到下方有個切換到Resource Bundle的按鈕,點選切換,添加國際化,然後分别在右側寫上對應國際化語言

SpringBoot+thymeleaf實作視圖控制器,攔截器,國際化功能

想添加多少,就可以添加多少。

5、可以在Thymeleaf頁面進行擷取了,用到thymeleaf文法中的擷取國際化語言标簽 #{}

6、一般來說我們在頁面會做個切換中英文的按鈕來進行切換

<a th:href="@{/login(lan='zn_CN')}">中文</a>
<a th:href="@{/login(lan='en_US')}">英文</a>
           

執行個體代碼:

<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<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">
  <title>使用者登入界面</title>
  <link th:href="@{/login/css/bootstrap.min.css}" rel="stylesheet">
  <link th:href="@{/login/css/signin.css}" rel="stylesheet">
</head>
<body class="text-center">
<!--  使用者登入form表單 -->
<form class="form-signin">
  <img class="mb-4" th:src="@{/login/img/login.jpg}" width="72" height="72">
  <h1 class="h3 mb-3 font-weight-normal" th:text="#{login.tip}" >請登入</h1>
  <input type="text" class="form-control"
         th:placeholder="#{login.username}"  required="" autofocus="">
  <input type="password" class="form-control"
         th:placeholder="#{login.password}"  required="">
  <div class="checkbox mb-3">
    <label>
      <input type="checkbox" value="remember-me">[[#{login.rememberme}]]
    </label>
  </div>
  <button class="btn btn-lg btn-primary btn-block" type="submit" th:text="#{login.button}" >登入
  </button>
  <p class="mt-5 mb-3 text-muted">© <span th:text="${currentYear}" >2018</span>-<span
          th:text="${currentYear}+1">2019</span></p>
  <a class="btn btn-sm" th:href="@{/login(l='zh_CN')}" >中文</a>
  <a class="btn btn-sm" th:href="@{/login(l='en_US')}">English</a>
</form>
</body>
</html>
           

7、做完上訴步驟,我們還需要編寫一個本地解析器來進行解析

public class MyLocaleResolver implements LocaleResolver {
    @Override
    public Locale resolveLocale(HttpServletRequest request) {
        // 接收語言的參數 - 傳進來的就是形如'zh_CN'這樣的參數
        String lan = request.getParameter("lan");
        // 使用預設的語言 - 在文中就是login.properties檔案裡配置的
        Locale locale = Locale.getDefault();
        // 判斷接收的參數是否為空,不為空就設定為該語言
        if(!StringUtils.isEmpty(lan)){
            // 将參數分隔 - 假設傳進來的是'zh_CN'
            String[] s = lan.split("_");
            // 語言編碼:zh   地區編碼:CN
            locale = new Locale(s[0],s[1]);
        }
        return locale;
    }

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

    }
}

           

8、我們在配置檔案中注入我們自定義的國際化解析器

SpringBoot+thymeleaf實作視圖控制器,攔截器,國際化功能
@Configuration
public class WebMvcConfig implements WebMvcConfigurer {
	@Bean
    public LocaleResolver localeResolver(){
        return new MyLocaleResolver();
    }
}
           

國際化就這樣完成了,通過上面定義的切換語言按鈕就可以切換了。