Spring MVC 国际化

概述

  首先熟悉一下Spring MVC的国际化结构。DispatcherServlet会解析一个LocaleResolver接口对象,通过它来决定用户区域(User Locale),读出对应用户系统设定的语言或者用户选择的语言,以确定其国际化。
  •AcceptHeaderLocaleResolver:Spring默认的区域解析器,它通过检验HTTP请求的acceptlanguage头部来解析区域。这个头部是由用户的web浏览器根据底层操作系统的区域设置进行设定。注意,这个区域解析器无法改变用户的区域,因为它无法修改用户操作系统的区域设置,所以它并不需要开发,因此也没有进一步讨论的必要。
  •FixedLocaleResolver:使用固定Locale国际化,不可修改Locale,这个可以由开发者提供固定的规则,一般不用,本书不再讨论它。
  •CookieLocaleResolver:根据Cookie数据获取国际化数据,由于用户禁止Cookie或者没有设置,如果是这样,它会根据acceptlanguage HTTP头部确定默认区域。
  •SessionLocaleResolver:根据Session进行国际化,也就是根据用户Session的变量读取区域设置,所以它是可变的。如果Session也没有设置,那么它也会使用开发者设置默认的值。

  为了可以修改国际化,Spring MVC还提供了一个国际化的拦截器——LocaleChangeInterceptor,通过它可以获取参数,然后既可以通过CookieLocaleResolver使用浏览器的Cookie来实现国际化,也可以用SessionLocaleResolver通过服务器的Session来实现国际化。但是使用Cookie的问题是用户可以删除或者禁用Cookie,所以它并非那么可靠,而使用Session虽然可靠,但是又存在过期的问题。不过在讨论国际化之前,还需要讨论如何加载国际化文件的问题,在Spring MVC中它就是MessageSource接口的使用问题。

MessageSource接口

  MessageSource接口是Spring MVC为了加载消息所设置的接口,我们通过它来加载对应的国际化属性文件
  其中Spring MVC一共提供了4个非抽象的实现类作为其子类。StaticMessageSource类是一种静态的消息源,DelegatingMessageSource实现的是一个代理的功能,这两者在实际应用中使用并不多,ResourceBundleMessageSource和ReloadableResourceBundleMessage Source在实际应用中使用较多,所以着重介绍它们。
  ResourceBundleMessageSource和ReloadableResourceBundleMessageSource的区别主要在于:ResourceBundleMessageSource使用的是JDK提供的ResourceBundle,它只能把文件放置在对应的类路径下。它不具备热加载的功能,也就是需要重启系统才能重新加载它。而ReloadableResourceBundleMessageSource更为灵活,它可以把属性文件放置在任何地方,可以在系统不重新启动的情况下重新加载属性文件,这样就可以在系统运行期修改对应的国际化文件,重新定制国际化的内容。

  代码清单16-26:使用XML定义MessageSource接口

<!--MessageSource接口是Spring MVC为了加载消息所设置的接口-->
<!-- ResourceBundleMessageSource 和 ReloadableResourceBundleMessageSource可二者选其一 -->
<!--<bean id="messageSource" class="org.springframework.context.support.ResourceBundleMessageSource">
    <property name="defaultEncoding" value="UTF-8"/>
    <property name="basenames" value="msg"/>
</bean>-->
<bean id="messageSource" class="org.springframework.context.support.ReloadableResourceBundleMessageSource">
    <property name="defaultEncoding" value="UTF-8"/>
    <property name="basenames" value="classpath:message/msg"/>
    <property name="CacheSeconds" value="3600"/>
</bean>

 

CookieLocaleResolver和SessionLocaleResolver

  代码清单16-29:使用XML方式配合LocaleResolver

<!--根据Cookie数据获取国际化数据-->
<bean id="localeResolver" class="org.springframework.web.servlet.i18n.CookieLocaleResolver">
    <property name="cookieName" value="lang"/>
    <property name="cookieMaxAge" value="20"/>
    <property name="defaultLocale" value="zh_CN"/>
</bean>
<!--根据Session进行国际化-->
<!--<bean id="localeResolver" class="org.springframework.web.servlet.i18n.SessionLocaleResolver">-->
<!--<property name="defaultLocale" value="zh_CN"/>-->
<!--</bean>-->

  只是对于Cookie而言,用户可以进行删除甚至禁用,使得其安全性难以得到保证,导致大量的使用默认值,也许这些并不是用户所期待的。为了避免这个问题,一般用得更多的是Session-LocaleResolver,它是基于Session实现的,具有更高的可靠性。

国际化拦截器(LocaleChangeInterceptor)

  通过请求参数去改变国际化的值时,我们可以使用Spring提供的拦截器LocaleChangeInterceptor,它继承了HandlerInterceptorAdapter
  代码清单16-30:配置拦截器LocaleChangeInterceptor

<!--国际化拦截器(LocaleChangeInterceptor)-->
<mvc:interceptors>
    <mvc:interceptor>
        <mvc:mapping path="/message/*.do"/>
        <bean class="org.springframework.web.servlet.i18n.LocaleChangeInterceptor">
            <!--监控请求参数language-->
            <property name="paramName" value="language"/>
        </bean>
    </mvc:interceptor>
</mvc:interceptors>

  当请求到来时,首先拦截器会监控有没有language请求参数,如果有则获取它,然后通过使用系统所配置的LocaleResolver实现国际化,不过需要注意的是,有时候获取不到参数,或者获取的参数的国际化并非系统能够支持的主题,这个时候会采用默认的国际化主题,也就是LocaleResolver所调用的setDefaultLocale方法指定的国际化主题。

开发国际化

  国际化的开发,首先需要新建两个国际化的属性文件msg_en_US.properties和msg_zh_CN.properties。
  •msg_en_US.properties
  welcome=the project name is chapter16
  •msg_zh_CN.properties
  welcome=\u5DE5\u7A0B\u540D\u79F0\u4E3A\uFF1Achapter16

  代码清单16-31:国际化JSP文件

<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8" %>
<%@taglib prefix="mvc" uri="http://www.springframework.org/tags/form" %>
<%@taglib prefix="spring" uri="http://www.springframework.org/tags" %>
<html>
<head>
    <title>Spring MVC国际化</title>
</head>
<body>
<h2>
    <!-- 找到属性文件变量名为welcome的配置 -->
    <spring:message code="welcome"/>
</h2>
Locale: ${pageContext.response.locale }
</body>
</html>

 

  代码清单16-32:国际化控制器

package com.ssm.chapter15.controller;

import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;

@Controller
@RequestMapping("/message")
public class MessageController {

    /**
     * http://localhost:8081/message/msgpage.do
     * http://localhost:8081/message/msgpage.do?language=en_US
     */
    @RequestMapping("/msgpage")
    public String page(Model model) {
        return "msgpage";
    }

}

 

posted @ 2019-07-06 15:19  草木物语  阅读(453)  评论(0编辑  收藏  举报