國際化:頁面響應式佈局同頁面針對不一樣的設備進行相應的顯示,國際化則是同頁面針對不一樣的地區/語言進行相應的自適應的顯示web
國際化消息資源的封裝類,主要配置不一樣地區和國家相應對象的表示內容,通常使用properties文件進行封裝spring
Locale對象的解析器,主要用於解析Locale對象以及負責Locale對象在Session中存儲mvc
Locale對象改變攔截器(可理解成Tomcat的監聽器:區別在於前者Servlet採用Servlet容器實現,Spring採用IOC容器實現),當頁面的locale對象發生改變時,該攔截器會進行相應的處理,不然不處理app
工做流程:核心類:LocaleChangeInterceptoride
public static final String DEFAULT_PARAM_NAME = "locale"; private String paramName = DEFAULT_PARAM_NAME; @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; }
preHandle:HandlerInterceptor接口的標準方法,主要用於Handler處理前的攔截處理,從LocaleChangeInterceptor的源碼可看出,當頁面請求參數包含locale的參數時,內部會自動建立和DispatherServlet綁定的localeResolver對象(例如SessionLocaleResolver),而後調用佈局
localeResolver.setLocale(request, response, parseLocaleValue(newLocale))
進行Locale對象的設置,這裏咱們查看setLocale方法在SessionLocaleResolver中的實現:this
@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對象去獲取不一樣的頁面顯示的資源文件,達到不一樣的語言/地區頁面不一樣的顯示的效果spa
注意:debug
<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>
目錄結構:code
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
<bean id="localeResolver" class="org.springframework.web.servlet.i18n.SessionLocaleResolver"/>
<mvc:interceptors> <bean class="org.springframework.web.servlet.i18n.LocaleChangeInterceptor"/> </mvc:interceptors>
@RequestMapping("/handlerInernationization/i18n") public String handlerInernationization(Locale locale) { String user = resourceBundleMessageSource.getMessage("i18n.title", null, locale); System.err.println("resourceBundleMessageSource:" + locale + ":i18n.title=" + user); return "i18n"; }
效果: 訪問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