转载

spring mvc国际化

国际化由三个部分组成

1、国际化资源(message_zh_CN.properties)加载

2、localResolver的配置

3、页面添加<spring:message>元素,使用资源中的key

由javacoder.cn整理, 转载注明出处

下面分别介绍

1、国际化资源(message_zh_CN.properties)加载

配置实现了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}

2、localResolver的配置

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, 不然不会使用的

3、<spring:message>使用

页面如下

<%@ 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来判断那个按钮被选中

效果如图:

spring mvc国际化

4、内部原理介绍

无论是那种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

原文  http://www.javacoder.cn/?p=1218
正文到此结束
Loading...