【Spring】- 資源國際化

國際化:頁面響應式佈局同頁面針對不一樣的設備進行相應的顯示,國際化則是同頁面針對不一樣的地區/語言進行相應的自適應的顯示web

SpringMVC支持的國際化的3個類

ResourceBundleMessageSource:

國際化消息資源的封裝類,主要配置不一樣地區和國家相應對象的表示內容,通常使用properties文件進行封裝spring

SessionLocaleResolver:

Locale對象的解析器,主要用於解析Locale對象以及負責Locale對象在Session中存儲mvc

LocaleChangeInterceptor:

Locale對象改變攔截器(可理解成Tomcat的監聽器:區別在於前者Servlet採用Servlet容器實現,Spring採用IOC容器實現),當頁面的locale對象發生改變時,該攔截器會進行相應的處理,不然不處理app

SpringMVC國際化工做原理圖

工做流程:核心類: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

  • ①:一個DispatcherServlet只會與LocaleResolver綁定
  • ②:客戶端訪問SpringMVC時,首先LocaleResolver判斷是否在Session中設置Locale/TimeZone對象,若是未設置則採起默認的Locale和TimeZone的獲取流程獲取
  • ③:Locale默認對象獲取流程:首先從LocaleResolver註冊到IOC容器的初始化參數獲取(可選:設置defaultLocale屬性),若是未配置則從客戶端的request中讀取Locale(請求頭)

SpringMVC國際化的配置

  1. 配置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>

目錄結構: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
  1. 配置LocaleResolver
<bean id="localeResolver" class="org.springframework.web.servlet.i18n.SessionLocaleResolver"/>
  1. 配置LocaleChangeInterceptor:
<mvc:interceptors>
<bean class="org.springframework.web.servlet.i18n.LocaleChangeInterceptor"/>
</mvc:interceptors>
  1. Handler
@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

相關文章
相關標籤/搜索