国际化由三个部分组成
1、国际化资源(message_zh_CN.properties)加载
2、localResolver的配置
3、页面添加<spring:message>元素,使用资源中的key
由javacoder.cn整理, 转载注明出处
下面分别介绍
配置实现了MessageSource接口的bean
<bean id="messageSource" class="org.springframework.context.support.ResourceBundleMessageSource"> <property name="basenames" value="message"/> <property name="useCodeAsDefaultMessage" value="true"/> </bean>
basenames表示资源文件的基础路径, 对于message_zh_CN.properties文件就为"message", 需要message_zh_CN.properties文件放在classes目录下,如果是其他目录请改为相应的路径
useCodeAsDefaultMessage表示properties文件中没有code对应的项时直接在页面输出code,而不是报错
新建两个properties文件
message_en_US.properties 内容如下
hello=hello {0} , {1}
message_zh_CN.properties内容如下
hello=/u4F60/u597D {0} , {1}
spring mvc默认配置的LocalResolver 为AcceptHeaderLocaleResolver, 根据http请求头"accept-language"来加载相应的国际化资源。
本例我们使用CookieLocaleResolver,如果cookie中有local信息我们就使用cookie中的,如果没有就是用CookieLocaleResolver的defaultLocale属性的值,如果defaultLocale属性没配置,那么使用http头" accept-header"的值。
配置如下
<bean id="localeResolver" class="org.springframework.web.servlet.i18n.CookieLocaleResolver"> <property name="defaultLocale" value="en_US"/> </bean>
参考DispatcherServlet.initLocaleResolver()代码,CookieLocaleResolver的id必须为localeResolver, 不然不会使用的
页面如下
<%@ page isELIgnored ="false" %> <%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %> <%@ taglib prefix="spring" uri="http://www.springframework.org/tags"%> <%@ taglib uri="/WEB-INF/classes/jc_tag.tld" prefix="jctag" %> <html> <head> <style type="text/css"> .selected { border: 1px solid #ff0000; } </style> <script type="text/javascript" src="/test-mvc/js/jquery-3.2.1.js"></script> <script type="text/javascript"> $(function(){ $("#zh_CN,#en_US").on("click", function(e){ var i18n = $(this).attr("id"); $.ajax({ type: "POST", dataType: "html", url:"/test-mvc/setCookie.do?i18n=" + i18n }) .done(function(data){ console.log("setCookie:" + data.isOK); window.location.reload(); }); }); }); </script> </head> <body> <button id="zh_CN" <jctag:locale locale="zh_CN">class="selected"</jctag:locale> >chinese</button> <button id="en_US" <jctag:locale locale="en_US">class="selected"</jctag:locale> >english</button><br> <spring:message code="hello" arguments="${username },${msg }"/> <spring:theme></spring:theme> </body> </html>
添加一个设置cookie的处理方法
@RequestMapping("setCookie") public void setCookie(HttpServletRequest request, HttpServletResponse response) { String newLocale = request.getParameter("i18n"); 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)); } response.setContentType("application/json"); try { response.getWriter().write("{isOK:true}"); } catch (IOException e) { e.printStackTrace(); } }
当用户点击相关的按钮后发送ajax改变语言, 然后window.location.reload();刷新页面,加载的就是如期望国际化后的页面
自己定制了<jctag:locale>tag来判断那个按钮被选中
效果如图:
无论是那种LocaleResolver的实现, DispatcherServlet.doService()将LocaleResolver添加到httpServletRequest中,便于页面渲染使用
org.springframework.web.servlet.support.RequestContext.initContext()方法中有如下代码
request.setAttribute(LOCALE_RESOLVER_ATTRIBUTE, this.localeResolver);
大家仔细思考,这两处的localeResolver是同一个实例。
spring的ApplicationContext也实现了MessageSource接口, 所有查找资源时先去ApplicationContext中查找真正加载资源的MessageSource,也就是我们本例配置的ResourceBundleMessageSource
Posted in:spring practise