SpringMVC 资源国际化实现以及常见问题
资源国际化可以很方便的实现web项目语言的切换,解决了web项目按需显示不同语言界面的问题.
SpringMVC 的资源国际化基于JDK的java.util.ResourceBundle实现,经过SpringMVC的封装实现起来非常简单:
简单实现具体步骤如下:
1.在SpringMVC的配置文件中配置ResourceBundleMessageSource(该类的作用是绑定资源文件,根据Locale值不同,显示不同的语言)
<!-- 资源国际化相关配置 -->
<bean id="messageSource" class="org.springframework.context.support.ResourceBundleMessageSource">
<!-- 如果在国际化资源文件中找不到对应代码的信息,就用这个代码作为名称 -->
<property name="useCodeAsDefaultMessage" value="true" />
<!-- 默认编码格式为 utf-8 -->
<property name="defaultEncoding" value="UTF-8" />
<!-- 国际化信息所在的文件名 -->
<property name="basenames">
<list>
<value>i18n.messages</value>
</list>
</property>
</bean>
(PS:basenames属性,值为资源文件的地址)
2.配置LocaleResolver(该类指明了Locale应该存放在何处)
LocaleResolver有三种选择,分别是基于request,基于session,基于cookie,因为基于request的实现不支持手动切换,建议使用基于session的实现
三种方式的配置具体如下:
a.基于request的实现:
<!-- 基于request实现资源国际化 -->
<bean id="localeResolver" class="org.springframework.web.servlet.i18n.AcceptHeaderLocaleResolver" />
b.基于session的实现:
<!-- 基于Session实现资源国际化 -->
<bean id="localeResolver" class="org.springframework.web.servlet.i18n.SessionLocaleResolver">
<property name="defaultLocale" value="en"/>
</bean>
c.基于cookie的实现
<!-- 基于cookie实现资源国际化 -->
<bean id="localeResolver" class="org.springframework.web.servlet.i18n.CookieLocaleResolver">
<property name="defaultLocale" value="en"/>
</bean>
3.配置localeChangeInterceptor拦截器(该类的作用是根绝不同的LocaleResolve采用不同的方式设置Locale)
<mvc:interceptors>
<bean id="localeChangeInterceptor"
class="org.springframework.web.servlet.i18n.LocaleChangeInterceptor">
<property name="paramName" value="langType" />
</bean>
</mvc:interceptors>
(paramName属性,是指请求中 切换语言的参数名)
4.编写资源文件
资源文件的命名规则是 basename [ _language ] [ _country ] [ _variant ].properties
languange country variant 需要为Locale类中的值
5.页面获取资源文件中的值(以jsp为例)
<%@ taglib prefix="spring" uri="http://www.springframework.org/tags" %> <spring:message code="comment.management" /> <!-- code的值为资源文件中对应的key -->
6.页面切换语言
这种方式实现的资源国际化,会拦截所有的请求,只要请求中带有 localeChangeInterceptor 中定义的参数,拦截器就会修改存储的Locale,实现语言的切换
常见问题(重点):
1.基于session不使用拦截器实现
a.查看LocaleChangeInterceptor源码,逻辑很简单就是看看请求中是否有语言类型的参数,如果有新建一个Locale,然后从request中取出一个LocaleResolver ,然后执行setLocale()方法,
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)
throws ServletException { String newLocale = request.getParameter(this.paramName);
if (newLocale != null) {
LocaleResolver localeResolver = RequestContextUtils.getLocaleResolver(request);
if (localeResolver == null) {
throw new IllegalStateException("No LocaleResolver found: not in a DispatcherServlet request?");
}
localeResolver.setLocale(request, response, StringUtils.parseLocaleString(newLocale));
}
// Proceed in any case.
return true;
}
b.查看源码,逻辑也很简单就是将Locale属性放到session中而已
public void setLocale(HttpServletRequest request, HttpServletResponse response, Locale locale) {
WebUtils.setSessionAttribute(request, LOCALE_SESSION_ATTRIBUTE_NAME, locale);
}
c.看到这里相信大伙应该心里有数啦,只要我们自己写一个Controller,然后根据我们自定义的参数,自己生成Locale主动放入session中即可,这样就可以去掉配置的拦截器
@RequestMapping(value = "/changeLanguage", method = RequestMethod.POST)
public @ResponseBody Language changeLanguage(HttpServletRequest request,
@RequestParam(value = "langType", defaultValue = "zh") String langType) { // 获取语言类型
Language language = Language.getLanguage(langType);
// 设置语言并放入session中
Locale locale = new Locale(language.getLanguage(), language.getCountry());
request.getSession().setAttribute(SessionLocaleResolver.LOCALE_SESSION_ATTRIBUTE_NAME, locale); return language;
}
2.资源文件的加载顺序
a.不得不说这是一个比较坑的问题,首先看现象吧
配置如下文件:
messages_en.properties
messages.properties 这里默认是中文
当运行在中文环境下,切换按钮没有问题,语言可以正常的切换,
当运行在英文环境下,切换按钮失效,怎么点都是英文,此时我满脸蒙蔽。
b.问题原因,好吧,既然有问题就只能继续研究呗,最后发现资源文件的加载顺序如下:
baseName _ 指定的language _ 指定的country_ 指定的variant
baseName _ 指定的language _ 指定的country
baseName _ 指定的language
baseName _默认的language _默认的country_默认的variant
baseName _默认的language _默认的country
baseName_默认的language
baseName
我们可以看出,加载顺序为:
优先加载指定国际化内容,之后加载默认国际化内容,最后加载顶级文件
c.解决方法在springMVC中配置LocaleResolve的时候指定默认语言(基于session,基于cookie)
<!-- 基于cookie实现资源国际化 -->
<bean id="localeResolver" class="org.springframework.web.servlet.i18n.CookieLocaleResolver">
<property name="defaultLocale" value="en"/>
</bean>
(以上,祝愉快!)
SpringMVC 资源国际化实现以及常见问题的更多相关文章
- springmvc 资源国际化
<!-- 关于国际化: 1. 在页面上能够根据浏览器语言设置的情况对文本(不是内容), 时间, 数值进行本地化处理 2. 可以在 bean 中获取国际化资源文件 Locale 对应的消息 3. ...
- SpringMVC实现国际化过程中所遇问题
前言:在利用SpringMVC实现国际化的过程中,看似简单,实则还是遇到了一些小问题,现在笔者对所遇问题总结如下. 注:笔者所用的编辑器为Intellij IEDA 14.1.7版本 1.国际化资源文 ...
- 一起学SpringMVC之国际化
随着网络的发展,在Web开发中,系统的国际化需求已经变得非常的普遍.本文主要讲解SpringMVC框架对多语言的支持,仅供学习分享使用,如有不足之处,还请指正. 什么是国际化? 国际化(interna ...
- 游戏UI框架设计(7): 资源国际化技术
游戏UI框架设计(7) --资源国际化技术 说起"资源国际化"技术,个人认为可以追述到微软Window2000 PC操作系统的发布,在这之前windows98操作系统的开发都是先由 ...
- springMVC项目国际化(i18n)实现方法
SpringMVC项目国际化(i18n)实现方法 按照作息规律,每周五晚必须是分享知识的时间\(^o^)/~,这周讲点儿啥呢,项目需要逼格,咱们国际化吧(* ̄rǒ ̄)~,项目中碰到这类需求的童鞋可能并 ...
- Struts第八篇【资源国际化、对比JSP的资源国际化】
资源国际化 我们在学JSTL标签的时候就涉及到了资源国际化,,,但是呢,在JSP的章节我并没有写博文来讲解怎么弄-.一方面感觉JSP的资源国际化好麻烦,另一方面是感觉用的地方很少-..因此就没有深入去 ...
- Android:认识R类、findViewById方法查找组件、@string查找字符、@color查找颜色、@drawable查找图片、@dimen某个组件尺寸定义、项目引入资源国际化
导入 之前都是断断续续的看了一些于如何使用android开发的文章.资料等,到目前位置很多基础的东西都不清楚,于是去学习了别人的课程,才了认识了R类.findViewById方法查找组件.项目引入资源 ...
- Struts2【UI标签、数据回显、资源国际化】
Struts2UI标签 Sturts2为了简化我们的开发,也为我们提供了UI标签...也就是显示页面的标签..... 但是呢,Struts2是服务端的框架,因此使用页面的标签是需要在服务器端解析然后再 ...
- JAVA WEB开发中的资源国际化
为什么要国际化? 不同国家与地区语言,文化,生活习惯等差异.在数字,时间,语言,货币,日期,百分数等的不同. 两个名词: I18N:即资源国际化,全称为Internationalization,因为首 ...
随机推荐
- mui.fire() 和 mui.trigger()
导读:添加自定义事件监听操作和标准js事件监听类似,可直接通过window对象添加,通过mui.fire()方法可触发目标窗口的自定义事件 监听自定义事件 添加自定义事件监听操作和标准js事件监听类似 ...
- 关于Fragment API版本号兼容问题
Fragment 是在API 11(android 3.0)被引入的.然而我的应用 的 android:miniSdkVersion 是 API 8,也就是说该应用是兼容旧版本号的.为了可以兼容旧版 ...
- (转)java 打印自身代码——真实世界不存在自指
public class SelfPrint { public static void main(String args[]) { char s = 34; ...
- android js 互相调用
代码地址如下:http://www.demodashi.com/demo/13107.html android js 互相调用 第二版 支持js匿名函数接收 支持js json对象接收 支持js函数返 ...
- WP8简单的计算器
<Grid x:Name="LayoutRoot" Background="Transparent"> <Grid.RowDefinition ...
- 关于行内元素之间有空隙的问题,例如span与input之间
问题如图: 想要的是下面的效果,而却出现上面的效果,解决方法如下: 对于行元素span或者input来说 很多人会用inline-block来显示他们,但是往往发现 中间会留一段小空隙 , 其实这个 ...
- AMD 3600+ X2 CPU配合昂达A69T主板超频教程
本次超频使用电脑硬件配置如下: AMD 3600+ X2 90nm 昂达 A69T HDMI 宇瞻 DDR II 1G 667普条 西数 WD2500KS SATAII 250G 16M 戴尔 普通 ...
- unity, 自定义类中使用print
在unity脚本中自定义c#类,而且不继承MonoBehaviour的话,若还想在其中使用print函数,可以用MonoBehaviour.print(...).
- Atitit.upnp SSDP 查找nas的原理与实现java php c#.net c++
Atitit.upnp SSDP 查找nas的原理与实现java php c#.net c++ 1. 查找nas的原理1 2. 与dlna的关系1 3. 与ssdp的关系1 4. Cling - Ja ...
- VLC Web插件的浏览器兼容性
网页插件实现原理 IE浏览器基于Activex插件来实现,非IE浏览器采用NPAPI来实现,所以,非浏览器需要支持NPAPI来实现. IE浏览器 FF浏览器(版本小于52) 原因从 Firefox 版 ...