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,共同窗习、共同进步,谢谢!

相关文章
相关标签/搜索