资源国际化可以很方便的实现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 资源国际化实现以及常见问题的更多相关文章

  1. springmvc 资源国际化

    <!-- 关于国际化: 1. 在页面上能够根据浏览器语言设置的情况对文本(不是内容), 时间, 数值进行本地化处理 2. 可以在 bean 中获取国际化资源文件 Locale 对应的消息 3. ...

  2. SpringMVC实现国际化过程中所遇问题

    前言:在利用SpringMVC实现国际化的过程中,看似简单,实则还是遇到了一些小问题,现在笔者对所遇问题总结如下. 注:笔者所用的编辑器为Intellij IEDA 14.1.7版本 1.国际化资源文 ...

  3. 一起学SpringMVC之国际化

    随着网络的发展,在Web开发中,系统的国际化需求已经变得非常的普遍.本文主要讲解SpringMVC框架对多语言的支持,仅供学习分享使用,如有不足之处,还请指正. 什么是国际化? 国际化(interna ...

  4. 游戏UI框架设计(7): 资源国际化技术

    游戏UI框架设计(7) --资源国际化技术 说起"资源国际化"技术,个人认为可以追述到微软Window2000 PC操作系统的发布,在这之前windows98操作系统的开发都是先由 ...

  5. springMVC项目国际化(i18n)实现方法

    SpringMVC项目国际化(i18n)实现方法 按照作息规律,每周五晚必须是分享知识的时间\(^o^)/~,这周讲点儿啥呢,项目需要逼格,咱们国际化吧(* ̄rǒ ̄)~,项目中碰到这类需求的童鞋可能并 ...

  6. Struts第八篇【资源国际化、对比JSP的资源国际化】

    资源国际化 我们在学JSTL标签的时候就涉及到了资源国际化,,,但是呢,在JSP的章节我并没有写博文来讲解怎么弄-.一方面感觉JSP的资源国际化好麻烦,另一方面是感觉用的地方很少-..因此就没有深入去 ...

  7. Android:认识R类、findViewById方法查找组件、@string查找字符、@color查找颜色、@drawable查找图片、@dimen某个组件尺寸定义、项目引入资源国际化

    导入 之前都是断断续续的看了一些于如何使用android开发的文章.资料等,到目前位置很多基础的东西都不清楚,于是去学习了别人的课程,才了认识了R类.findViewById方法查找组件.项目引入资源 ...

  8. Struts2【UI标签、数据回显、资源国际化】

    Struts2UI标签 Sturts2为了简化我们的开发,也为我们提供了UI标签...也就是显示页面的标签..... 但是呢,Struts2是服务端的框架,因此使用页面的标签是需要在服务器端解析然后再 ...

  9. JAVA WEB开发中的资源国际化

    为什么要国际化? 不同国家与地区语言,文化,生活习惯等差异.在数字,时间,语言,货币,日期,百分数等的不同. 两个名词: I18N:即资源国际化,全称为Internationalization,因为首 ...

随机推荐

  1. python基础语法(四)

    --------------------------------------------接 Python 基础语法(三)---------------------------------------- ...

  2. vue 项目中 自定义 webpack 的 配置文件(webpack.config.babel.js)

    webpack.config.babel.js,这样命名是想让webpack在编译的时候自动识别es6的语法,现在貌似不需要这样命名了,之前用webpack1.x的时候貌似是需要的 let path ...

  3. 【Python3 爬虫】09_正则表达式(re.math()、re.search()、re.sub()、全局匹配函数)

    re.math()函数 从源字符串的起始位置匹配一个模式 语法:re.match(pattern, string, flag) 第一个参数代表对应的正则表达式,第二个参数代表对应的源字符,第三个参数是 ...

  4. Codeforces 476C Dreamoon and Sums (水

    题目链接:点击打开链接 题意: 给定a,b 对于一个数x.若x是nice number,则满足(x/b)/(x%b) == [1,a](即结果在1-a之间) 问: 输出一个数表示 全部nice num ...

  5. Linux如何关机与关机命令祥解

    Linux关机命令祥解 1.直接关电源 2.init 0 3.telinit 0 4.shutdown -h now 5.halt6.poweroff 1.shutdown shutdown命令安全地 ...

  6. linux中的dd复制命令

    dd命令用于复制文件并对原文件的内容进行转换和格式化处理.dd命令功能很强大的,对于一些比较底层的问题,使用dd命令往往可以得到出人意料的效果.用的比较多的还是用dd来备份裸设备.但是不推荐,如果需要 ...

  7. iOS-NSMutableParagraphStyle段落风格

    apple API: NS_CLASS_AVAILABLE(10_0, 6_0) @interface NSMutableParagraphStyle : NSParagraphStyle @prop ...

  8. html5_websocket_tomcat8

    目录 前言 后端 浏览器前端 java的client 注意 前言 HTML5 WebSocket实现了服务器与浏览器的双向通讯,开销小,实时性高,常用于即时通讯和对信息实时性要求比较高的应用. 下面讲 ...

  9. libevent源码学习_event_test

    对应的sample文件中提供了event_test.c,里面就是关于事件的简单示例,具体如下: /* * Compile with: * cc -I/usr/local/include -o even ...

  10. Eclipse maven 项目红叉 编译不报错问题处理

    项目右键-> Maven ->  Update Maven Project 选中 :Force update 复选框