Spring MVC 国际化

发布于:2024-04-18 ⋅ 阅读:(29) ⋅ 点赞:(0)

国际化

基本概念

国际化 是开发支持多语言和数据格式的应用程序的技术,无需重新编写编程逻辑。国际化单词 internationlization 常缩写为 i18n

本地化 这是将国际化应用程序改成支持特定 语言区域 (locale)的技术。语言区域是指一个特定的地理、政治或文化区域。会影响到文字、时间日期格式等的形式。

在 Java 中,java.util.Locale 类表示一个语言区域。一个 Locale 对象主要包含 2 个主要概念:language(语言) 和 country(国家)。为此 国家化标准组织 专门制定了 ISO 639 标准(用于标识语言)和 ISO 3166标准(用于标识国家)。

SpringMVC 的国际化问题,就是回答两个问题:

  • 提供资源文件在哪里?(以及如何加载?
  • 如何获得 Locale 对象?(以决定使用哪个资源文件
  1. 如何加载某个地方的资源文件,常见有两种途径。
  2. 如何获得 Locale 对象,有三种途径。

使用国际化功能,再次强调,不要直接访问 JSP 页面,而是通过 Controller「转到」JSP 页面,因为 JSP 页面的显示,需要 Spring MVC 做一些准备工作,一旦「绕过」Controller,导致「准备工作」不充分会造成 JSP 页面无法正常显示。

指明(并加载)资源文件

资源文件有固定的命名规则:有一个任意的基准名,后面再接下划线、语言码,还可以选择加一条下划线和国家码。如:

  • messages_zh_CN.properties
  • messages_en_US.properties
  • messages_de_DE.properties

这里 基准名 是代表这一系列文件的标志,后续所使用的「文件名」或「文件路径名」的概念,通常都只算到 基准名 部分位置。

在 Spring MVC 中,通过配置 ReloadableResourceBundleMessageSource 类,或 ResourceBundleMessageSource 类来查找/加载上述资源文件。

<bean id="messageSource" class="
        org.springframework.context.support .ReloadableResourceBundleMessageSource">
    <property name="basenames">
         <list>
         <value>classpath:message</value>      <!-- 需要使用 classpath 关键字 -->
       </list>
    </property>
</bean>

<bean id="messageSource" class="
        org.springframework.context.support.ResourceBundleMessageSource">
    <property name="basenames">
        <list>
             <value>message</value>          <!-- 不需要使用 classpath 关键字 -->
        </list>
    </property>
</bean>

以上两个类二选一,让 Spring 容器去创建其中一个的单例对象即可。对它们两个的配置,就相当于实现了国际化的第一步:告诉 Spring MVC 资源文件在哪

获得 Locale 对象

在第一步工作告知 Spring MVC 资源文件在什么地方后,Spring MVC 需要考虑的就是如果获取 Locale 对象,以决定使用「一堆」资源文件中的哪一个。

Spring MVC 有三种方式获得 Locale 对象:

  • AcceptHeaderLocaleResolver,从 Http 请求头中获取
  • SessionLocaleResolver,从 Session 对象中获取
  • CookieLocaleResolver,从 Cookie 对象中获取

注意,以上三种途径是互斥的,期望采用那种途径,就让 Spring 去创建/维护这个类的一个单例对象。且名字必须为 localeResolver

AcceptHeaderLocaleResolver

AcceptHeaderLocaleResolver 是 Spring MVC 默认的区域解析器,它会在 HTTP 请求的 accept-language 头部查找 Locale 信息,并以此决定使用哪个资源文件。

这个头部是由用户的web浏览器根据底层操作系统的区域设置进行设定。

SessionLocaleResolver

AcceptHeaderLocaleResolver 它会从当前请求的 Session 中查找Locale信息,如果 Session 中没有,那么它会根据 accept-language 头部信息确定区域信息。

<bean id="localeResolver" class="org.springframewrok.web.servlet
    .i18n.SessionLocaleResolver">
    <property name="defaultLocale" value="en"/>
</bean>

CookieLocaleResolver

CookieLocaleResolver 它会从请求的 cookie 中查找 Locale 信息,如果 cookie 中没有,那么它会根据 accept-language 头部信息确定区域信息。

这个区域解析器所采用的 Cookie 可以通过 cookieName 和 cookieMaxAge 属性进行定制。cookieMaxAge 属性表示这个 Cookie 应该持续多少秒,-1表示这个 Cookie 在浏览器关闭之后就失效。

<bean id="localeResolver" class="org.springframework.web.servlet.i18n.CookieLocaleResolver">
    <property name="cookieName" value="language"/>
    <property name="cookieMaxAge" value="3600"/>
    <property name="defaultLocale" value="en"/>
</bean>

修改 Locale 信息

非常规办法

如果使用的是 AcceptHeaderLocaleResolver,那么需要修改用户的浏览器设置,以实现locale信息的修改。

如果使用的是 SessionLocaleResolverCookieLocaleResolver,可以在代码中通过显示调用 LocaleResolver.setLocale() 来修改客户端的 locale 信息,并且该信息会存储于 Session,或 Cookie 中。但这不是首选方案。

常规办法: LocaleChangeInterceptor 拦截器

Spring MVC 提供了 LocaleChangeInterceptor 拦截器,该拦截器会发现当前 HTTP 请求中出现的 特殊参数 。如果这种参数出现在当前请求中,拦截器就会根据参数值来改变用户的区域。

<mvc:interceptors>
    <bean id="localeChangeInterceptor" class="org.springframework.web.servlet.i18n.LocaleChangeInterceptor">
        <property name="paramName" value="lang"/>
    </bean>
</mvc:interceptors>
http://localhost:8080/court/welcome.do?lang=en_US
http://localhost:8080/court/welcome.do?lang=zh_CN