`
zuxianghuang
  • 浏览: 6794 次
  • 性别: Icon_minigender_1
  • 来自: 深圳
文章分类
社区版块
存档分类
最新评论

springmvc i18n

阅读更多
SPRING MVC国际化问题解决方案
1 解决途径
(1)将所有包含中文的资源文件(包括JS、图片、JSP等),翻译成多套;
(2)使用属性文件(Properties文件)配置JSP文件的语言,JS和图片等资源使用多套;
第一种解决方案较为简单,但对于业务逻辑变动较频繁的应用来说不是很适用;第二种解决方案,虽然会对开发进度有一定的影响,但相对比较灵活。
本文以第二种解决方案为主线进行讨论。
2 网络解决方案
对于SPRING MVC国际化的问题,网络上提供的解决方案大致如下:
一、基于浏览器语言的国际化配置
使用Spring的MVC,并且配置中有配置Resource文件。
<bean id="messageSource"
class="org.springframework.context.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参数,而是request.getLocale()方法,即浏览器的语言配置。事实上,当按照“基于请求的国际化配置”的方法进行配置后,在浏览器端传递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()方法)及其相应的实现类(LanguageRequestFromAppconfig、LanguageRequestFromHostName、LanguageRequestFromRequestHeader、LanguageRequestFromUserSelection),用于表示国际化解决方案的不同配置。编写过滤器,用于拦截请求,并对设置的资源文件进行处理。resolveLocale()直接从languageRequest中获得相应的locale。在四个实现类中,分别实现相应的locale获得机制。
4.3 配置流程
4.3.1 web配置
目的:配置过滤器代理,使得过滤器可以通过Spring注入的方式来进行配置,方便属性的设置。WEB配置如下。
<filter>
<filter-name>filterChainProxy</filter-name>
<filter-class>
org.springframework.web.filter.DelegatingFilterProxy
</filter-class>
<init-param>
<param-name>encoding</param-name>
<param-value>utf-8</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>filterChainProxy</filter-name>
<url-pattern>/*</url-pattern>
<dispatcher>REQUEST</dispatcher>
</filter-mapping>
4.3.2 Spring配置
所谓的Spring配置是指applicationContext.xml文件的配置。下面给出了此国际化解决方案的最全配置。
<!-- 系统支持的语言包 -->
<bean id="cnLocale" class="java.util.Locale">
<constructor-arg value="zh"></constructor-arg>
<constructor-arg value="CN"></constructor-arg>
</bean>
<bean id="enLocale" class="java.util.Locale">
<constructor-arg value="en"></constructor-arg>
<constructor-arg value="US"></constructor-arg>
</bean>
<!-- 本应用安装的语言资源列表 -->
<bean id="localeResource" class="cn.csdb.international.resource.LocaleResource">
<property name="installedLocaleList">
<list>
<ref bean="cnLocale"/>
<ref bean="enLocale"/>
</list>
</property>
</bean>

<!-- 系统需要处理的资源类型,即需要配置过滤的资源 -->
<bean id="handleResourceType" class = "cn.csdb.international.resource.HandleResourceType">
<property name="list">
<list>
<value>.jpg</value>
<value>.gif</value>
<value>.png</value>
<value>.js</value>
<value>.css</value>
</list>
</property>
<property name="filterList">
<list>
<value>dwr/</value>
</list>
</property>
</bean>

<!-- 系统配置默认的语言包 -->
<bean id="appConfig" class="cn.csdb.international.request.LanguageRequestFromAppconfig" >
<!--  覆盖默认的session存储,而使用cookie存储locale,cookie有效期为一个月
<property name="medium" value="cookie"></property>
-->
<property name="appLocale" ref="cnLocale" />
<property name="localeParameterStatus" value="true"></property>
</bean>

<!-- 系统根据URL地址来设定语言包 -->
<bean id="hostName" class="cn.csdb.international.request.LanguageRequestFromHostName">
<property name="urlLocaleMap">
<map>
<entry key="localhost" value-ref="cnLocale"></entry>
<entry key="127.0.0.1" value-ref="enLocale"></entry>
</map>
</property>
</bean>

<!-- 系统根据浏览器语言来设定语言包 -->
<bean id="request" class="cn.csdb.international.request.LanguageRequestFromRequestHeader">
<!--  覆盖默认的session存储,而使用cookie存储locale,cookie有效期为一个月
<property name="medium" value="cookie"></property>
-->
<property name="localeParameterStatus" value="true"></property>
</bean>

<!-- 系统根据用户选择即locale参数来设定语言包 -->
<bean id="userSel" class="cn.csdb.international.request.LanguageRequestFromUserSelection">
<!--  覆盖默认的session存储,而使用cookie存储locale,cookie有效期为一个月
<property name="medium" value="cookie"></property>
-->
</bean>

<!—
localeResover,要实现多语言显示,则必须配置localeResover,且名称不允许更改;
否则,系统自动按照浏览器语言来显示
-->
<bean id="localeResolver" class= "cn.csdb.international.resolver.MyLocaleResolver">
<property name="languageRequest" ref="request"></property>
</bean>

<!-- 国际化使用的过滤器 -->
<!--
对于资源文件来说,当遇到多语言处理时,系统自动寻找WEB-INF/lang路径底下的语言文件夹,加载对应的资源文件;
如webroot/common/js/jquery/jquery-min.js,遇到多语言处理时,系统自动加载webroot/WEB-INF/lang/locale/common/js/jquery/jquery-min.js;
因此,要配置多语言环境,需要在将所有想要国际化的资源文件放在WEB-INF/lang底下,且default目录是必须的
-->
<bean id="internationalFilter" class="cn.csdb.international.filter.InternationalFilter">
<property name="localeResolver" ref="localeResolver"></property>
<property name="handleResourceType" ref="handleResourceType"></property>
<!-- 缓存文件中需要包括名为“resFileCache”的缓存 -->
<property name="cacheConfigFile" value="/WEB-INF/ehcache.xml"></property>
</bean>

<!-- 配置语言资源文件的地址 -->
<bean id="messageSource"
class="org.springframework.context.support.ResourceBundleMessageSource">
<property name="basename" value="message/message" />
<property name="useCodeAsDefaultMessage" value="true" />
</bean>

<!-- 过滤规则的配置 -->
<bean id ="filterChainProxy" class ="org.springframework.security.util.FilterChainProxy">
<property name="stripQueryStringFromUrls" value="false"/>
<property name="matcher">
<bean class ="org.springframework.security.util.RegexUrlPathMatcher"/>
</property>
<property name ="filterChainMap">
<map>
<entry key="/.*">
<list>
<ref bean="internationalFilter"/>
</list>
</entry>
</map>
</property>
</bean>
如上所述,本配置为此方案的最全配置,仅起到参考作用。实际应用过程中,可以根据需求来进行相应的删减。以下是部分配置的说明:
(1)本应用安装的语言资源列表:当应用需要读取其支持的语言时,以进行进一步的配置时,可以通过得到此Bean (LocaleResource),进而得到应用所支持的语言。比如:利用VDB Model Buider进行建模时,需要读取当前支持的语言包,并为每套语言提供一套配置界面。如无此需求,可以不进行配置;
(2)系统需要处理的资源类型:locale语言本身仅能解决页面国际化显示的问题,而不能解决诸如JS、JPEG、GIF等资源文件的国际化,而这对于国际化应用来说又是必须的。比如:中文系统的某个JS提示可能为:”对不起,您不允许进行此操作“,而对应的英文系统应有对应的英文提示,可能为:“Sorry, You have no Privilege!”(建议JS文件中尽量少写中文)。此时,就需要有各个语言版本的JS、JPEG以及GIF等资源文件。不同的locale,加载不同的资源文件,分别存储在“/WEB-INF/lang/语言”目录下。其list主要用来配置需要处理的资源文件类型,filterList主要用来排除某些特定的资源文件类型,如dwr所用到的JS等。
(3)国际化配置类型:本方案支持四种国际化配置类型,如有需要,还可以通过继承LanguageRequest来实现自己的国际化配置类型。四种国际化配置类型分别如下:
①LanguageRequestFromAppconfig:表示根据应用的配置来设置浏览器显示的语言,而不管浏览器端使用的是何种语言。有三个属性:medium:表示存储介质,可以使用session和cookie两种方式来存储;appLocale:默认显示的语言;localeParameterStatus:是否支持url中的locale参数;如果支持浏览器端参数,则当用户选定(通过URL参数来传递)某个语言版本后,在session或者cookie不失效的情况下,均为用户选择的语言。
②LanguageRequestFromHostName:表示根据主机名称来加载浏览器端显示的语言,而不管浏览器端使用的是何种语言。有一个属性:urlLocaleMap:用于存储主机地址与语言之间的映射关系。当使用对应的主机地址时,加载对应的语言版本;如遇不支持的语言,则显示默认值(default)。
③LanguageRequestFromRequestHeader:表示根据浏览器端语言来决定其显示。有两个参数:medium: 表示存储介质,可以使用session和cookie两种方式来存储;localeParameterStatus:是否支持url中的locale参数;如果支持浏览器端参数,则当用户选定(通过URL参数来传递)某个语言版本后,在session或者cookie不失效的情况下,均为用户选择的语言。
④LanguageRequestFromUserSelection:表示根据用户选择的语言来决定其显示。当用户不选定(不通过url传递locale参数)任何语言时,默认按照浏览器端的语言来展示。有一个参数:medium: 表示存储介质,可以使用session和cookie两种方式来存储。
在具体使用时,可以根据需求选择其中的一种进行配置。
(4)localeResolver:必须要配置。如果不配置localeResolver,则应用始终按照浏览器端来决定显示的语言。这在DispatcherServlet的工作原理中已经解释。localeResover有一个参数:languageRequest,用于设置用户选择的国际化配置类型。
(5)internationalFilter:本解决方案所使用的过滤器,必须要配置。用于对拦截的资源类型进行处理,并跳转到相应的语言目录下,加载不同语言版本的资源文件。如果没有要处理的资源文件,也需要配置此过滤器,如果不配置此过滤器,则系统不会将用户选择的语言存储到session或者cookie中。有三个属性:localeResolver:必须要配置;handleResourceType:如果没有要处理的资源文件类型,可以不配置;cacheConfigFile:ehCache缓存处理:如果不需要缓存处理,可以不进行配置(建议配置,否则每次请求时,都会有很多的文件IO操作)。
(6)messageSource:同Spring,配置多个语言版本的property文件的位置。
(7)filterChainProxy:过滤器规则的配置。
具体使用过程中,可以参考上述完整配置。
分享到:
评论

相关推荐

    基于SpingMvc i18n demo

    **SpringMvc i18n(国际化)Demo** 在Web开发中,为了使应用程序能够适应不同国家和地区的用户,实现多语言支持是至关重要的。SpringMvc框架提供了强大的国际化(i18n)功能,允许开发者轻松地根据用户的语言环境来...

    springmvc 实现i18n国际化+freemarker小实例demo

    在IT行业中,国际化(i18n)是一种技术,它允许软件产品和服务适应不同地区和语言的需求。Spring MVC作为Java Web开发中的一个强大框架,提供了支持i18n的机制。结合Freemarker模板引擎,我们可以构建出具有多语言功能...

    springmvc+国际化i18N+springmvc验证+jetbrick-template使用+@responsebody+谷歌guava

    springmvc+国际化i18N+springmvc验证+jetbrick-template使用+@responsebody+谷歌guava: 1)围绕springmvc做的国际化 2)围绕springmvc做的验证 3)使用的jetbrick-template模板引擎 ……

    Java SpringMVC实现国际化整合案例分析(i18n)

    国际化(Internationalization,通常缩写为i18n)是指软件能够适应不同语言和地区的功能。具体到Web应用,国际化允许网站展示不同语言的内容,以满足不同国家用户的阅读习惯。本文将详细介绍如何在Java SpringMVC...

    i18切换语言springmvc

    在IT行业中,国际化(i18n)是一个关键的特性,尤其对于开发多语言支持的Web应用程序来说。Spring MVC作为一款强大的MVC框架,提供了很好的支持来实现这一功能。"i18切换语言springmvc"这个项目就是针对如何在Spring...

    SpringMVC demo 完整源码实例下载.zip

    国际化(i18n)是使应用适应不同地区用户需求的关键。SpringMVC通过MessageSource接口和.properties资源文件支持多语言环境。源码中可能包含不同语言的资源文件,以及如何在视图层动态选择和显示对应语言的信息。 ...

    SpringMVC、jQuery国际化配置

    国际化(i18n)是一种设计和实现方式,使得软件可以根据用户的本地设置显示适当的文本和格式。 在SpringMVC中,国际化配置主要涉及以下几个方面: 1. **工程结构**:通常,你需要创建一个包含不同语言资源的目录...

    SpringMVC demo 完整源码实例下载

    国际化(Internationalization,i18n)是提供多语言支持的重要手段。SpringMVC通过ResourceBundle和MessageSource接口实现这一功能。开发者可以创建不同的消息资源文件,对应不同的语言,根据用户的浏览器设置动态...

    SpringMVC入门案例源码

    9. **国际化与主题支持**:SpringMVC提供了i18n(国际化)和theme(主题)的支持,可以根据用户的选择或系统设置来显示不同语言或主题的页面。 10. **异常处理**:通过@ControllerAdvice和@ExceptionHandler注解,...

    SpringMVC 入门教程.pdf

    - SpringMVC 提供了 i18n 国际化和 theme 主题支持,便于创建多语言和多主题的网站。 13. **RESTful 风格的支持** - SpringMVC 支持创建 RESTful 风格的 Web 服务,通过 HTTP 方法(GET、POST、PUT、DELETE)来...

    SpringMVC实战

    通过这个资源,你将有机会实践这些核心概念,并且可能还会了解到更多高级特性,比如Spring Security(安全控制)、Spring Session(会话管理)、国际化(i18n)和本地化(l10n)支持、缓存(Caching)以及单元测试等...

    springmvc web开发源码

    另外,也可能有国际化(Internationalization, i18n)和本地化(Localization, l10n)的支持,通过MessageSource接口提供多语言资源。 总的来说,这个"springmvc web开发源码"项目展示了如何使用SpringMVC作为Web...

    SpringMVC 4.0

    10. **国际化(Internationalization,i18n)**:SpringMVC通过MessageSource接口支持多语言环境,开发者可以轻松实现应用的国际化。 11. **MVC配置优化**:在SpringMVC 4.0中,可以使用Java配置替代XML配置,通过@...

    自定义的springMVC

    - **国际化(i18n)**:SpringMVC可以通过ResourceBundle和MessageSource支持多语言,可以根据用户的选择动态地加载不同语言的资源文件。 - **RESTful风格的URL**:通过配置SpringMVC,可以轻松实现RESTful风格的...

    基于SpringBoot 实现国际化配置的完整源码示例

    国际化的核心配置文件是`messages.properties`,通常位于`src/main/resources`下的`i18n`目录中。对于多语言支持,我们需要创建多个文件,如`messages_en.properties`(英文)和`messages_zh_CN.properties`(简体...

    跟开涛学SpringMVC源代码

    同时,还会讲解如何实现国际化(i18n)支持,让应用能够适应不同地区的用户。 6. **Chapter 6:SpringMVC高级特性** 这部分涵盖了SpringMVC的更多高级特性,比如拦截器(Interceptor)、上传文件、异步处理、...

    springMVC国际化登陆整合

    在这个"springMVC国际化登陆整合"项目中,我们将探讨SpringMVC如何与国际化(i18n)相结合,以及登录功能的实现。 1. **SpringMVC的国际化配置**: - 在SpringMVC项目中,国际化主要通过MessageSource接口实现,它...

    springmvc增删改,分页,导入数据等功能

    8. **国际化与本地化**:SpringMVC提供了i18n支持,允许根据用户的语言环境显示相应的文本资源,提升应用的全球化适应性。 通过以上讨论,我们可以看出SpringMVC在处理数据管理方面的能力非常强大,它提供了完善的...

    springmvc重构员工管理系统

    8. **国际化(i18n)支持**:SpringMVC提供对多语言的支持,通过ResourceBundle和MessageSource,可以轻松实现不同语言环境下的显示。 9. **异常处理**:可以使用@ControllerAdvice和@ExceptionHandler来全局处理可能...

Global site tag (gtag.js) - Google Analytics