您的位置:首页 > 编程语言 > Java开发

Springmvc国际化的工作原理

2017-02-16 11:56 501 查看
国际化:页面响应式布局一个页面针对不同的设备进行相应的显示,国际化则是也个页面针对不同的地区/语言进行相应的自适应的显示

SpringMVC支持的国际化的三个类:

ResourceBundleMessageSource:

国际化消息资源的封装类,主要配置不同地区和国家相应对象的表示内容,一般使用properties文件进行封装

SessionLocaleResolver:

Locale对象的解析器,主要用于解析Locale对象以及负责Locale对象在Session中的存储

LocaleChangeInterceptor:

Locale对象改变拦截器(可以理解成Tomcat的监听器:区别在于前者Servlet采用Servlet容器实现,Spring采用IOC容器实现),当页面的locale对象发生改变时,该拦截器会进行相应的处理,否则不处理

SpringMVC国际化的工作原理图:



工作流程:核心类:LocaleChangeInterceptor

核心源码:

@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)
throws ServletException {

String newLocale = request.getParameter(getParamName());
if (newLocale != null) {
if (checkHttpMethod(request.getMethod())) {
LocaleResolver localeResolver = RequestContextUtils.getLocaleResolver(request);
if (localeResolver == null) {
throw new IllegalStateException(
"No LocaleResolver found: not in a DispatcherServlet request?");
}
try {
localeResolver.setLocale(request, response, parseLocaleValue(newLocale));
}
catch (IllegalArgumentException ex) {
if (isIgnoreInvalidLocale()) {
logger.debug("Ignoring invalid locale value [" + newLocale + "]: " + ex.getMessage());
}
else {
throw ex;
}
}
}
}
return true;
}

public String getParamName() {
return this.paramName;
}

public static final String DEFAULT_PARAM_NAME = "locale";

private String paramName = DEFAULT_PARAM_NAME;


preHandle:HandlerInterceptor接口的标准方法,主要用于Handler处理前的拦截处理,从LocaleChangeInterceptor的源码可以看出,当页面请求参数包含locale的参数时,内部会自动创建和DispatherServlet绑定的localeResolver对象(例如SessionLocaleResolver),然后调用

localeResolver.setLocale(request, response, parseLocaleValue(newLocale))


进行Locale对象的设置,这里我们查看setLocale方法在SessionLocaleResolver中的实现:

@Override
public void setLocaleContext(HttpServletRequest request, HttpServletResponse response, LocaleContext localeContext) {
Locale locale = null;
TimeZone timeZone = null;
if (localeContext != null) {
locale = localeContext.getLocale();
if (localeContext instanceof TimeZoneAwareLocaleContext) {
timeZone = ((TimeZoneAwareLocaleContext) localeContext).getTimeZone();
}
}
WebUtils.setSessionAttribute(request, LOCALE_SESSION_ATTRIBUTE_NAME, locale);
WebUtils.setSessionAttribute(request, TIME_ZONE_SESSION_ATTRIBUTE_NAME, timeZone);
}


从源码中可以看出,SessionLocaleResolver主要完成Locale和TimeZone对象在Session中的存储,这样通过SpringMVC国际化整个流程的Locale和TimeZone的设置就全部完成了,当客户端访问对应的资源时IOC容器内部的ResourceBundleMessageSource会自动根据Locale对象去获取不同的页面显示的资源文件,达到不同的语言/地区页面不同的显示的效果

注意:

①:一个DispatcherServlet只会与LocaleResolver绑定

②:客户端访问SpringMVC时,首先LocaleResolver判断是否在Session中设置Locale/TimeZone对象,如果未设置则采取默认的Locale和TimeZone的获取流程获取

③:Locale默认对象获取流程:首先从LocaleResolver注册到IOC容器的初始化参数获取(可选:设置defaultLocale属性),如果未配置则从客户端的request中读取Locale(请求头)

SpringMVC国际化的配置:

①:配置ResourceBundleMessageSource:国际化资源:

<bean id="messageSource" class="org.springframework.context.support.ResourceBundleMessageSource">
<property name="defaultEncoding" value="UTF-8" />
<property name="useCodeAsDefaultMessage" value="true" />
<property name="basenames">
<list>
<value>config/i18n</value>
</list>
</property>
</bean>


目录结构:



i18n_en_US.properties:

user.name=name

user.passwd=passwd

page.language:English

page.description:Page Language

i18n.tile:Internationization

i18n_zh_CN.properties:

user.name:\u7528\u6237\u540D

user.passwd:\u5BC6\u7801

page.language:Simple Chinese

page.description:\u9875\u9762\u8BED\u8A00

i18n.tile:\u56FD\u9645\u5316

②:配置LocaleResolver

<bean id="localeResolver" class="org.springframework.web.servlet.i18n.SessionLocaleResolver"/>


③:配置LocaleChangeInterceptor:

<mvc:interceptors>
<bean class="org.springframework.web.servlet.i18n.LocaleChangeInterceptor"/>
</mvc:interceptors>


效果:

访问URL:http://127.0.0.1:8080/springmvc_experience/handlerInernationization/i18n?locale=zh_CN



访问URL:http://127.0.0.1:8080/springmvc_experience/handlerInernationization/i18n?locale=en_US

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息