SpringMVC之源碼分析--LocaleResolver(三)

概述

咱們繼續分析學習Spring MVC LocaleResolver,本節咱們分析使用的是SessionLocaleResolver。
SessionLocaleResolver與CookieLocaleResolver相似,運用用戶會話(session)實現LocaleResolver功能。html

解析器(SessionLocaleResolver)

SessionLocaleResolver類繼承關係以下圖:web

  • AbstractLocaleResolver抽象類,實現LocaleResolver,在該抽象類中定義默認的Locale屬性
  • LocaleContextResolver接口,繼承LocaleResolver,增長了TimeZone操做
  • AbstractLocaleContextResolver抽象類,繼承AbstractLocaleResolver類並實現LocaleContextResolver接口,定義了默認的TimeZone屬性
  • SessionLocaleResolver實現類,繼承AbstractLocaleContextResolver類,即完成操做Locale和TImeZone的功能

SessionLocaleResolver類容許從用戶請求會話中獲取Locale和TimeZone,和CookieLocaleResolver對比,該策略在Servlet容器的HttpSession中存儲客戶端使用Locale等設置,這是設置對於每一個會話(session)都是臨時的,會話終止時信息丟失。
入口是resolveLocaleContext(final HttpServletRequest request)方法,即Spring MVC接收到客戶端請求後,若是配置了SessionLocaleResolver,會調用此方法,源碼以下:spring

// 解析Locale等信息方法
@Override
public LocaleContext resolveLocaleContext(final HttpServletRequest request) {
    // 返回Locale和TimeZone
    return new TimeZoneAwareLocaleContext() {
        @Override
        public Locale getLocale() {
            // 從請求的會話中返回Locale
            Locale locale = (Locale) WebUtils.getSessionAttribute(request, localeAttributeName);
            if (locale == null) {
                locale = determineDefaultLocale(request);
            }
            return locale;
        }
        @Override
        @Nullable
        public TimeZone getTimeZone() {
            // 從請求的會話中返回TimeZone
            TimeZone timeZone = (TimeZone) WebUtils.getSessionAttribute(request, timeZoneAttributeName);
            if (timeZone == null) {
                timeZone = determineDefaultTimeZone(request);
            }
            return timeZone;
        }
    };
}

// 設置Locale和TimeZone
@Override
public void setLocaleContext(HttpServletRequest request, @Nullable HttpServletResponse response,
        @Nullable LocaleContext localeContext) {

    Locale locale = null;
    TimeZone timeZone = null;
    if (localeContext != null) {
        locale = localeContext.getLocale();
        if (localeContext instanceof TimeZoneAwareLocaleContext) {
            timeZone = ((TimeZoneAwareLocaleContext) localeContext).getTimeZone();
        }
    }
    // 把Locale設置到session中
    WebUtils.setSessionAttribute(request, this.localeAttributeName, locale);
    // 把TimeZone設置到session中
    WebUtils.setSessionAttribute(request, this.timeZoneAttributeName, timeZone);
}

實戰

  • 項目結構

參考http://www.javashuo.com/article/p-vlaxpnyl-es.html中的項目結構,本章與其一致。segmentfault

  • 配置文件

在Spring MVC配置文件中配置資源加載以及SessionLocaleResolver Bean,配置以下:瀏覽器

<!-- 國際化資源文件 -->
<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" />
    <!--<property name="defaultEncoding" value="ISO-8859-1"/>-->
</bean>
<mvc:interceptors>
    <!-- 該攔截器經過名爲」locale」的參數來攔截HTTP請求,使其從新設置頁面的區域化信息 -->
    <bean class="org.springframework.web.servlet.i18n.LocaleChangeInterceptor">
        <!-- 設置請求的參數名爲locale -->
        <property name="paramName" value="locale"/>
    </bean>
</mvc:interceptors>
<!-- SessionLocaleResolver解析器 -->
<bean id="localeResolver" class="org.springframework.web.servlet.i18n.SessionLocaleResolver">
    <!-- 設置session attribute的key -->
    <property name="localeAttributeName" value="locale"/>
    <!-- 設置默認的Locale -->
    <property name="defaultLocale" value="en"/>
</bean>
  • 屬性文件

參考http://www.javashuo.com/article/p-vlaxpnyl-es.html中的項目結構,本章與其一致。session

  • 控制器

編寫Controller控制器,以便測試,代碼以下:mvc

@GetMapping(value = "/getSessionLocale", produces = "text/html;charset=UTF-8")
@ResponseBody
public String sessionLocaleResolver(HttpServletRequest request) {
    RequestContext requestContext = new RequestContext(request);
    String value = requestContext.getMessage("message.locale");
    HttpSession session = request.getSession();
    return "Session中設置的Locale是:"+session.getAttribute("locale")+" </br>當前使用的Locale是:" + requestContext.getLocale() + " </br>使用的資源Locale文件是:messages_" + value+".properties";
}
  • 測試

瀏覽器發起請求http://localhost:8089/getSessionLocale?locale=en_US,結果以下圖:app

變動參數locale的值,請求http://localhost:8089/getSessionLocale?locale=zh_CN,結果以下圖:ide

測試結果代表Locale設置成功,本例驗證了SessionLocaleResolver的使用。學習

總結

  • 使用SessionLocaleResolver與LocaleChangeInterceptor結合使用來設置國際化
  • 大體流程爲:根據請求的語言參數,在過濾器中設置Locale,Spring就能夠根據設置區不一樣的屬性文件來實現國際化
  • 本系列主要分析了Spring MVC國際化的原理,有寫的不到位的地方還望好好包涵,有不書面不清晰的地方可留言,真心地但願跟你們一塊兒交流探討。

最後建立了qq羣方便你們交流,可掃描加入,同時也可加我qq:276420284,共同窗習、共同進步,謝謝!

相關文章
相關標籤/搜索