SPRING MVC国际化问题解决方案
1 解决途径
梦见如厕(1)将所有包含中文的资源文件(包括JS、图片、JSP等),翻译成多套;
(2)使用属性文件(Properties文件)配置JSP文件的语言,JS和图片等资源使用多套;
第一种解决方案较为简单,但对于业务逻辑变动较频繁的应用来说不是很适用;第二种解决方案,虽然会对开发进度有一定的影响,但相对比较灵活。
本文以第二种解决方案为主线进行讨论。
2 网络解决方案
对于SPRING MVC国际化的问题,网络上提供的解决方案大致如下:
一、基于浏览器语言的国际化配置
使用Spring的MVC,并且配置中有配置Resource文件。
<bean id="messageSource"
class="t.support.ResourceBundleMessageSource">
<property name="basename" value="message-info" />
<property name="useCodeAsDefaultMessage" value="true" />
</bean>
其中,message-info是properties文件的通用名。如:我的配置文件叫message- info.properties,message-info_zh_CN.properties等等,只要有了这个配置,然后配置JSP渲染器为JSTL 支持的,那么在你的JSP文件中使用fmt标记就可以实现客户浏览器语言国际化了。
如:<fmt:message key="info.login.title" />
其中的info.login.title和你的资源文件对应.
另外一种方式是使用spring自带的标签显示国际化信息,如:
<spring:message code="main.title" /><br>
<input type="button" value="<spring:message code="main.title" />"/><br>
二、基于动态加载的国际化配置
1、基于请求的国际化配置
基于请求的国际化配置是指,在当前请求内,国际化配置生效,否则自动以浏览器为主。
配置方式如下:
首先配置
<bean id="localeChangeInterceptor"
class="org.springframework.web.servlet.i18n.LocaleChangeInterceptor" />
这个配置呢,是不论请求级别的国际化,还是Cookie级别的国际化,再或者Session级别的国际化,都必需有配置这个,否则会不能使用。
配好上面的之后,就将注入到你的UrlHandlerMapping中,例如:
<bean id="defaultUrlMapping"
class="org.springframework.web.servlet.handler.BeanNameUrlHandlerMapping">
<property name="interceptors" ref="localeChangeInterceptor" />
<property name="order">
<value>1</value>
</property>
</bean>
这个时候,但凡有了符合UrlMapping的请求,就会被拦截,并且开始配置国际化参数
<bean id="localeResolver"
class="org.springframework.web.servlet.i18n.AcceptHeaderLocaleResolver">离离原上草全诗的诗名
</bean>
默认的参数名为locale主意大小写。里面放的就是你的提交参数。如:en_US,zh_CN之类的,这个时候,你在页面上加一句<a href="?locale=zh_CN">简体中文</a>
如果你的资源中,饱含建议中文的配置,那么就会变成你确定的简体中文啦。
2、基于Session的国际化配置
和基于请求的相同
Session的配置如下:
<bean id="localeResolver"
class="org.springframework.web.servlet.i18n.SessionLocaleResolver">
</bean>
在你的处理的Controller中,将提交上来的locale字段信息生成真正的Locale对象,然后将对象保存在Session中,默认保存的ID是SessionLocaleResolver.LOCALE_SESSION_ATTRIBUTE_NAME亡口月羊凡念什么
这样,当你的Session不过期,那么语言种类始终保持正确的说。我一直是这样子用的,我觉得还是Session的好,老外们用了很满意。
3、基于Cookie的国际化配置考研专业选择
<bean id="localeResolver"
class="org.springframework.web.servlet.i18n.CookieLocaleResolver"/>
三、注意事项
如果不用默认的浏览器语言国际化方式,那么一定要配置,如果你有多个UrlMapping,那么就每个都配上。
至于配置的LocaleResolver的名字,一定要用上面的配置中的名字localeResolver当然了,这个是默认的名字来的,自己设置成别的也可以,但是就是麻烦,反正我用默认的就感觉不错。
3 网络解决方案的BUG及局限性
对于网络解决方案中提到的“基于请求的国际化配置”,与基于浏览器语言的国际化配置是等价的。通过分析AcceptHeaderLocaleResolver的源码,发现“基于请求的国际化配置”调用的并不是浏览器上传递的locale参数,而是Locale()方法,即浏览器的语言配置。事实上,当按照“基于请求的国际化配置”的方法进行配置后,在浏览器端传递locale参数时,系统会提示如下错误:
Cannot change HTTP accept header - use a different locale resolution strategy
此异常是由AcceptHeaderLocaleResolver的setLocale方法抛出的。
由此可见,设置AcceptHeaderLocaleResolver起不到任何效果,不如直接使用基于浏览器端的国际化配置比较好。
此外,对于上面几种解决方案来说,重点解决的是显示层面的国际化问题,即通过locale参数来控制国际化语言,session和cookie只是存储locale参数的介质。
有些需求,通过上面提到的解决方案则无法解决。
(1)系统安装时,选择一个默认安装语言。不论浏览器语言的版本如何,默认均显示此语言;且通过locale参数,可以手动调整显示的语言;
(2)系统安装时,为不同语言的版本配置不同的URL;当访问此URL时,不管浏览器语言的设置如何,均显示此URL对应的语言版本;
4 SPRING MVC国际化解决方案
护考分数线前言:前面提供的网络解决方案也为SPRING MVC的国际化解决方案,但具有一定的局限性;接下来本文探讨一种基于Spring的i18n包实现的国际化解决方案。
4.1 Spring DispatcherServlet工作原理
DispatcherServlet为Spring的神经中枢,所有的请求与分发均要通过此Servlet。此Servlet会加载WEB以及applicationContext中的配置,以初始化相应的相应的参数。
对于Spring应用的国际化来说,最重要的参数有三个:localeResolver、localeChangeInterceptor以及messageSource。LocaleResolver在i18n中是一个接口,具有setLocale()和resolverLocale()两个方法,setLocale()方法用于在locale发生变化的时候调用,而localeChangeInterceptor用于监听浏览器端locale的变化(第一次访问此应用时,会调用此方法来设置locale;之后,如果locale有变化,则会调用setLocale()方法),resolveLocale()方法主要用于获得当前的locale(如果为空,则返回浏览器端的locale),在多个地方均会调用此方法获得当前的locale,其中对于页面显示最重要的一处为DispatcherServlet的render()方法。这个地方获得的locale直接决定浏览器端页面显示的语言,通过resolveLocale()得到的locale即为setLocale()方法设置的值。Spring中,AcceptHeaderLocaleResolver, SessionLocaleResolver什么是私募基金, CookieLocaleResolver分别是LocaleResolver的三种实现,这在前面的网络解决方案中已经讨论,这里不再赘述。
当spring配置文件中,没有配置localeResolver时,spring会默认的使用org.springframework.web.servlet.i18n.AcceptHeaderLocaleResolver(缺省策略)。AcceptHeaderLocaleResolver表示接受浏览器端的语言设置,即根据浏览器端的语言来setLocale()。也就是说,如果不设置localeResolver,render()时调用resolverLocale()方法获得的locale始终是浏览器端的语言。在render之前通过filter,interceptors以及servlet等对locale进行修改也无济于事。因为在spring MVC中,当所有的filter,interceptors以及servlet执行完毕后,DispatcherServlet的render()方法此时会调用localeResolver的resolveLocale方法,获得当前的locale对象。然后set到response中去。
因此,要想控制页面浏览器端页面的显示,必须配置localeResolver。而采用Spring自带的LocaleResolver接口的实现,无法满足上述提及的需求,且无法处理诸如图片类的资源文件。
4.2 实现思路
自定义类实现LocaleResolver接口的setLocale()和resolveLocale(),编写LanguageRequest抽象类(包括getLocale()方法)及其相应的实现类(LanguageRequest
FromAppconfig、LanguageRequestFromHostName、LanguageRequestFromRequestHeader、LanguageRequestFromUserSelection),用于表示国际化解决方案的不同配置。编写过滤器,用于拦截请求,并对设置的资源文件进行处理。resolveLocale()直接从languageRequest中获得相应的locale。在四个实现类中,分别实现相应的locale获得机制。
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论