Spring MVC 框架学习七:Spring MVC 实现本地化

我们先来看在页面上如何根据浏览器语言设置情况对文本进行本地化处理

src下新建三个properties 文件

i18n.properties

i18n.msg=This is a English Page

i18n_en_US.properties

i18n.msg=This is a English Page

i18n_zh_CN.properties 值为 "这是一个中文页面"

i18n.msg=\u8FD9\u662F\u4E00\u4E2A\u4E2D\u6587\u9875\u9762

配置 spring 配置文件 springmvc.xml

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xmlns:mvc="http://www.springframework.org/schema/mvc"
    xmlns:context="http://www.springframework.org/schema/context"
    xsi:schemaLocation="http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-4.0.xsd
        http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
        http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.0.xsd">

    <!-- 配置自动扫描的包 -->
    <context:component-scan base-package="com.bupt.springmvc.converter"></context:component-scan>
    
    <!-- 配置视图解析器 -->
    <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
        <property name="prefix" value="/WEB-INF/views/"></property>
        <property name="suffix" value=".jsp"></property>
    </bean>
    
    <!-- 配置国际化资源文件 -->
    <bean id="messageSource" class="org.springframework.context.support.ResourceBundleMessageSource">
        <property name="basename" value="i18n"></property>
    </bean>
    
    <mvc:view-controller path="i18n" view-name="i18n"/>    
</beans>

配置 web.xml

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xmlns="http://xmlns.jcp.org/xml/ns/javaee"
    xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd"
    id="WebApp_ID" version="3.1">

    <!-- 自定义的spring 配置文件可以放置在类路径 src下,名字在 param-value 属性中指定 -->
    <servlet>
        <servlet-name>springDispatcherServlet</servlet-name>
        <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
        <init-param>
            <param-name>contextConfigLocation</param-name>
            <param-value>classpath:springmvc.xml</param-value>
        </init-param>
        <load-on-startup>1</load-on-startup>
    </servlet>

    <servlet-mapping>
        <servlet-name>springDispatcherServlet</servlet-name>
        <url-pattern>/</url-pattern>
    </servlet-mapping>
    
</web-app>

编写 index.jsp 和 i18n.jsp 页面

<a href="i18n">i18n page</a>
<fmt:message key="i18n.msg"/>

 

启动 tomcat,访问 index.jsp,点击超链接时,页面跳转为(测试时以IE或FireFox浏览器为工具,Chrome浏览器本地化不是这样配置的)

 

当把语言切换为英语时

 

 访问页面的内容变为

如此,在不同的浏览器语言环境设置下,文本也随着进行本地化处理

 

前面我们在页面上显示出了国际化资源文件中的信息,那在后台怎么获取呢?我们需要配置一个方法处理器类

@Controller
public class ConverterHandler
{    
    @Autowired
    private ResourceBundleMessageSource messageSource;
    
    @RequestMapping("/i18n")
    public String testI18n(Locale locale)
    {
        String msg = messageSource.getMessage("i18n.msg", null, locale);
        System.out.println(msg);
        return "i18n";
    }  
}

 

当再次以不同的语言设置访问页面时,控制台的信息输出也会随着语言的不同而输出不同的消息

 

我们经常能看到有的网站会在页面上提供语言切换的图标,这种语言切换功能不要求用户更改浏览器设置,它们通过 Cookie、Session 或 请求参数即可切换本地化类型,为用户的使用带来方便。

在默认情况下,SpringMVC 根据 Accepti-Language 参数判断客户端的本地化类型,此外它还提供了多种指定客户端本地化类型的方式:通过 Cookies、Session 指定。事实上当收到请求时,SpringMVC 在上下文中寻找一个本地化解析器(LocaleResolver),找到后使用它获取请求所对应的本地化类型信息。

除此之外,SpringMVC 还允许装配一个动态更改本地化类型的拦截器,这样通过指定一个请求参数就可以控制单个请求的本地化类型。本地化解析器和拦截器都定义在 org.springframework.web.servlet.i18n 包中,用户可以在 DispatcherServlet 上下文中配置它们。

 

Spring 提供以下四个本地化解析器

1. AcceptHeaderLocaleResolver:根据 HTTP 报文头的 Accept-Language 参数确定本地化类型,如果没有显式定义本地化解析器,SpringMVC 默认采用 AcceptHeaderLocaleResolver。

2. CookiesLocaleResolver:根据指定 Cookie 值确定本地化类型

3. SessionLocaleResolver:根据 Session 中特定的属性值确定本地化类型

4. LocaleChangeInterceptor:从请求参数中获取本次请求对应的本地化类型

 

来看代码实现

首先我们需要在 springmvc.xml 中新增配置 SessionLocaleResolver 来代替默认的 AcceptHeaderLocaleResolver,同时还需要配置 LocaleChangeInterceptor

    <bean id="localeResolver" class="org.springframework.web.servlet.i18n.SessionLocaleResolver"/>
    
    <mvc:interceptors>
        <bean class="org.springframework.web.servlet.i18n.LocaleChangeInterceptor"/>
    </mvc:interceptors>

 

index.jsp 新增如下代码

    <br><br>
    <a href="i18n?locale=zh_CN">中文</a>
    <a href="i18n?locale=en_US">English</a>

 

访问index.jsp页面,效果如图

 

分别点击 中文 和 English 效果如图

同时控制台的输出为

可以看到通过配置,我们可以实现不用手动去改变浏览器配置只需要点击相应链接就能完成本地化的切换。

 

其中 SessionLocaleResolver 和 LocaleChangeInterceptor 工作流程如下图所示

 

 

我们再来看一下底层代码的整个流程是什么样子的

SpringMVC 在处理一般请求时都需要经过 DispatcherServlet 的 doDispatch 方法,它会调用 handle 方法获取经过方法处理器处理后的 ModelAndView 对象 mv,再将对象交由 processDispatchResult 处理,经过渲染输出成最后的页面。

 

但由于我们在配置文件中配置了拦截器 LocaleChangeInterceptor,所以在调用 handler 方法前还需要经过 PreHandler() 方法的处理。它会获取我们配置的 LocaleResolver 对象,同时把 request 携带的名为 locale 的请求参数转换为 Locale 对象,放置到 LocaleResolver 对象中去,如图

 

跟踪 setLocale()方法,发现它其实调用的是 setLocaleContext 方法,找到它最后的实现类 SessionLocaleResolver。调用 setSessionAttribute 把 Locale 对象放置到Session 域当中去了

 

 

之后,方法重回到 handle 方法获取 ModelAndView 对象,当调用 render 方法对 ModelAndView 对象进行渲染时,它会通过传递来的 HttpServletRequest 对象获取到之前放置在 Session 域中的 Locale 对象,最后把 Locale 对象和 ModelAndView 一起放置到视图解析器中去解析得到最后的效果页面

 

 以上就是 SpringMVC 处理本地化的底层代码流程。

 

posted on 2016-07-15 15:45  Traveling_Light_CC  阅读(410)  评论(0编辑  收藏  举报

导航