SpringMVC之原始碼分析–LocaleResolver和ThemeResolver應用

NO IMAGE
1 Star2 Stars3 Stars4 Stars5 Stars 給文章打分!
Loading...

概述

以上分析了Spring MVC的LocaleResolver和ThemeResolver兩個策略解析器,在實際專案中很少使用,尤其是ThemeResolver,花精力去分析他們,主要是為了系統的學習,更多的瞭解Spring為我們提供的功能元件,通過這個過程,我本人也有了更多的體會,就像上篇文章(https://segmentfault.com/a/1190000014873033)最後提出的小需求,需求本身不是具有實際意義,其實就是讓自己去思考,加深已學知識的理解,不知道小夥伴們有沒有思考呢?廢話不多說,現在就去實現它。

需求

根據客戶端環境,介面顯示不同的國旗圖案。

分析

在接到一個需求時,首先要理解需求,實際工作中可能需求跟產品進行多次溝通,其目的就是準確的理解,理解了需求就可以選擇相應的技術方案去解決。就我們這個功能來說,需求就是可定製不同的國旗圖案。選擇的技術方案可利用Spring MVC提供的國際化和主題定製來解決。

實現

  • 專案結構
  • 原始碼分析

    • pom.xml檔案

      引入Spring MVC依賴以及JSP依賴,程式碼如下:

      <!-- Spring MVC依賴 -->
      <dependency>
          <groupId>org.springframework</groupId>
          <artifactId>spring-webmvc</artifactId>
          <version>5.0.5.RELEASE</version>
      </dependency>
      <dependency>
      <!-- Servlet支援 -->
      <groupId>javax.servlet</groupId>
          <artifactId>javax.servlet-api</artifactId>
          <version>3.1.0</version>
          <scope>provided</scope>
      </dependency>
      <!-- jsp支援-->
      <dependency>
          <groupId>javax.servlet</groupId>
          <artifactId>jstl</artifactId>
          <version>1.2</version>
      </dependency>
      
    • spring-servlet.xml檔案

      在classpath下新建Spring MVC配置檔案,程式碼如下:

      <!-- 啟動註解掃描 -->
      <mvc:annotation-driven/>
      
       <!-- mvc controller -->
      <context:component-scan base-package="com.github.dalianghe.controller" />
      
      <!-- 預設Servlet處理靜態資源 -->
      <mvc:default-servlet-handler />
      
      <!-- jsp檢視對映與檢視解析 -->
      <bean id="viewResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver">
          <property name="viewClass" value="org.springframework.web.servlet.view.JstlView"/>
          <property name="prefix" value="/WEB-INF/jsp/"/>
          <property name="suffix" value=".jsp"/>
      </bean>
      
      <mvc:interceptors>
          <!-- 該攔截器通過引數名為”locale”的引數來攔截HTTP請求,設定LocaleResolver -->
          <bean class="org.springframework.web.servlet.i18n.LocaleChangeInterceptor">
              <property name="paramName" value="locale"/>
          </bean>
      </mvc:interceptors>
      
      <!-- 國際化資原始檔 -->
      <bean id="messageSource" class="org.springframework.context.support.ReloadableResourceBundleMessageSource">
          <!-- 如果資原始檔放在classpath下,basename的value必須有classpath:字首,否則報錯:No message found under code... -->
          <property name="basename" value="classpath:i18n/messages" />
          <!-- 如果在國際化資原始檔中找不到對應程式碼的資訊,就用這個程式碼作為名稱返回  -->
          <property name="useCodeAsDefaultMessage" value="true" />
      </bean>
      
       <!--CookieLocaleResolver解析器 -->
      <bean id="localeResolver" class="org.springframework.web.servlet.i18n.CookieLocaleResolver">
          <!-- 設定預設為中國,即從客戶端cookie中未找到cookieName時,使用預設locale -->
          <property name="defaultLocale" value="zh_CN"/>
          <!-- 設定cookieName,預設為:org.springframework.web.servlet.i18n.CookieLocaleResolver.LOCALE -->
          <property name="cookieName" value="locale"/>
      </bean>
      
      <!-- 載入主題資原始檔 -->
      <bean id="themeSource" class="org.springframework.ui.context.support.ResourceBundleThemeSource">
          <!-- 指定檔案字首,即檔案所在目錄,如果放在classpath下,value為空(預設從classpath下載入) -->
          <property name="basenamePrefix" value="theme."/>
      </bean>
      
      <!-- 主題解析器 -->
      <bean id="themeResolver" class="org.springframework.web.servlet.theme.CookieThemeResolver">
          <!-- 主題檔名稱,如果有多個相同字首(theme)時,
                 查詢最終的檔名為: defaultThemeName 國際化標識,如:theme_zh_CN.properties-->
          <property name="defaultThemeName" value="theme"/>
          <!-- 設定theme的客戶端cookie名 -->
          <property name="cookieName" value="theme"/>
      </bean>
      
    • web.xml檔案

      配置Spring MVC 前端控制器,即DispatcherServlet,負責攔截使用者請求,程式碼如下:

      <servlet>
          <!-- Servlet名稱,可任意定義,但必須與servlet-mapping中對應 -->
          <servlet-name>dispatcher</servlet-name>
          <!-- 指定Spring MVC核心控制類,即J2EE規範中的前端控制器(Front Controller) -->
          <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
          <!-- 指定Spring MVC配置檔案,預設在WEB-INF目錄下,
              切名字為[servlet-name]-servlet.xml,此檔案中配置web相關內容,
              比如:指定掃描Controller路徑、配置邏輯檢視字首字尾、上傳檔案等等 -->
          <init-param>
              <param-name>contextConfigLocation</param-name>
              <param-value>classpath:spring-servlet.xml</param-value>
          </init-param>
          <!-- 此配置的值為正整數時,表示容器啟動時初始化,即呼叫Servlet的init方法 -->
          <load-on-startup>1</load-on-startup>
          <async-supported>true</async-supported>
      </servlet>
      <!-- 定義servlet對映 -->
      <servlet-mapping>
          <!-- 與servlet中servlet-name對應 -->
          <servlet-name>dispatcher</servlet-name>
          <!-- 對映所有的url -->
          <url-pattern>/</url-pattern>
      </servlet-mapping>
      
    • 國際化屬性檔案

      本例中建立了中國、美國及芬蘭的國際化支援,配置檔案如下:

      messages_zh _CN.properties

      message.locale=中國
      

      messages_en _US.properties

      message.locale=美國
      

      messages_sv _FI.properties

      message.locale=芬蘭
      
    • 主題屬性檔案

      根據國際化配置,主題定義了中國、美國及芬蘭的國旗圖片,配置如下:

      theme_ zh_CN.properties

      background=/img/China.jpg
      

      theme_ en_US.properties

      background=/img/America.jpg
      

      theme_ sv_FI.properties

      background=/img/Finland.jpg
      
    • 檢視及控制器

      Controller控制器程式碼如下:

      @RequestMapping("/demo")
      public String demo(HttpServletRequest request , Model model){
      
          Locale locale = RequestContextUtils.getLocale(request);
      
          model.addAttribute("locale",locale);
      
          return "demo";
      }
      

      JSP檢視程式碼如下:

      <%@ page contentType="text/html;charset=UTF-8" %>
      <%@ taglib prefix="fmt" uri="http://java.sun.com/jstl/fmt" %>
      <%@ taglib prefix="spring" uri="http://www.springframework.org/tags"%>
      <html>
          <head>
          <title>Spring MVC Theme</title>
          </head>
          <body>
              <fmt:message key="message.name"/> : <fmt:message key="message.locale"/>
              <br/><br/>
              <img src="<spring:theme code='background'/>" style="width: 500px;height: 300px;">
          </body>
      </html>
      
  • 功能測試

本例以Firefox為客戶端測試工具,測試步驟如下:

1、啟動專案後,訪問介面,在位址列輸入http://localhost:8088/demo,結果如下:

由圖可知,此時系統使用的是預設的國際化屬性檔案及顯示預設的國旗圖案,與我們設想的一致。注意此時返回的cookie中沒有國際化及主題相關的資訊。

2、通過請求引數locale設定地區環境,在位址列輸入localhost:8088/demo?locale=en_US,併發起請求,結果如下:

由上圖可知結果,與我們的設想一致,並且服務端通過攔截器把國際化寫入了客戶端cookie中。

3、修改請求引數locale的值為荷蘭,即locale=sv_FI後再發起請求,結果如下:

與預期一致,測試通過。

總結

本例使用CookieLocaleResolver和CookieThemeResolver結合實現了國際化與主題定製需求,Spring MVC為我們提供了不通實現方式的LocaleResolver和ThemeResolver,可自由組合使用,這兩個策略解析器主要定製前端資訊或樣式,通過之前的原始碼分析及此案例,這塊內容就分析完了,希望對大家有所幫助。

相關文章

開發語言 最新文章