springMVC源码分析--国际化LocaleResolver(一)

springMVC给我们提供了国际化支持,简单来说就是设置整个系统的运行语言,然后根据系统的运行语言来展示对应语言的页面,一般我们称之为多语言。springMVC国际化机制就是可以设置整个系统的运行语言,其定义了一个国际化支持接口LocaleResolver,提供的默认实现类如下图。


springMVC国际化提供了四个默认实现的类AcceptHeaderLocaleResolver,FixedLocaleResolver、CookieLocaleResolver和SessionLocaleResolver。接下来我们简单介绍一下这四个实现类的源码。

AcceptHeaderLocaleResolver:其实没有任何具体实现,是通过浏览器头部的语言信息来进行多语言选择。

[java]  view plain  copy
 print ? 在CODE上查看代码片 派生到我的代码片
  1. public class AcceptHeaderLocaleResolver implements LocaleResolver {  
  2.   
  3.     @Override  
  4.     public Locale resolveLocale(HttpServletRequest request) {  
  5.         return request.getLocale();  
  6.     }  
  7.   
  8.     @Override  
  9.     public void setLocale(HttpServletRequest request, HttpServletResponse response, Locale locale) {  
  10.         throw new UnsupportedOperationException(  
  11.                 "Cannot change HTTP accept header - use a different locale resolution strategy");  
  12.     }  
  13.   
  14. }  
FixedLocaleResolver:设置固定的语言信息,这样整个系统的语言是一成不变的,用处不大。

[java]  view plain  copy
 print ? 在CODE上查看代码片 派生到我的代码片
  1. public class FixedLocaleResolver extends AbstractLocaleContextResolver {  
  2.     public FixedLocaleResolver() {  
  3.         setDefaultLocale(Locale.getDefault());  
  4.     }  
  5.     public FixedLocaleResolver(Locale locale) {  
  6.         setDefaultLocale(locale);  
  7.     }  
  8.     public FixedLocaleResolver(Locale locale, TimeZone timeZone) {  
  9.         setDefaultLocale(locale);  
  10.         setDefaultTimeZone(timeZone);  
  11.     }  
  12.     @Override  
  13.     public Locale resolveLocale(HttpServletRequest request) {  
  14.         Locale locale = getDefaultLocale();  
  15.         if (locale == null) {  
  16.             locale = Locale.getDefault();  
  17.         }  
  18.         return locale;  
  19.     }  
  20.     @Override  
  21.     public LocaleContext resolveLocaleContext(HttpServletRequest request) {  
  22.         return new TimeZoneAwareLocaleContext() {  
  23.             @Override  
  24.             public Locale getLocale() {  
  25.                 return getDefaultLocale();  
  26.             }  
  27.             @Override  
  28.             public TimeZone getTimeZone() {  
  29.                 return getDefaultTimeZone();  
  30.             }  
  31.         };  
  32.     }  
  33.   
  34.     @Override  
  35.     public void setLocaleContext(HttpServletRequest request, HttpServletResponse response, LocaleContext localeContext) {  
  36.         throw new UnsupportedOperationException("Cannot change fixed locale - use a different locale resolution strategy");  
  37.     }  
  38.   
  39. }  
CookieLocaleResolver:将语言信息设置到Cookie中,这样整个系统就可以获得语言信息

[java]  view plain  copy
 print ? 在CODE上查看代码片 派生到我的代码片
  1. public class CookieLocaleResolver extends CookieGenerator implements LocaleContextResolver {  
  2.   
  3.     //多语言cookie名称  
  4.     public static final String LOCALE_REQUEST_ATTRIBUTE_NAME = CookieLocaleResolver.class.getName() + ".LOCALE";  
  5.   
  6.     //多语言时区cookie名称  
  7.     public static final String TIME_ZONE_REQUEST_ATTRIBUTE_NAME = CookieLocaleResolver.class.getName() + ".TIME_ZONE";  
  8.   
  9.       
  10.     //默认的多语言cookie名称  
  11.     public static final String DEFAULT_COOKIE_NAME = CookieLocaleResolver.class.getName() + ".LOCALE";  
  12.   
  13.     private Locale defaultLocale;  
  14.   
  15.     private TimeZone defaultTimeZone;  
  16.   
  17.     public CookieLocaleResolver() {  
  18.         setCookieName(DEFAULT_COOKIE_NAME);  
  19.     }  
  20.     public void setDefaultLocale(Locale defaultLocale) {  
  21.         this.defaultLocale = defaultLocale;  
  22.     }  
  23.   
  24.     protected Locale getDefaultLocale() {  
  25.         return this.defaultLocale;  
  26.     }  
  27.   
  28.     public void setDefaultTimeZone(TimeZone defaultTimeZone) {  
  29.         this.defaultTimeZone = defaultTimeZone;  
  30.     }  
  31.   
  32.     protected TimeZone getDefaultTimeZone() {  
  33.         return this.defaultTimeZone;  
  34.     }  
  35.   
  36.   
  37.     @Override  
  38.     public Locale resolveLocale(HttpServletRequest request) {  
  39.         parseLocaleCookieIfNecessary(request);  
  40.         return (Locale) request.getAttribute(LOCALE_REQUEST_ATTRIBUTE_NAME);  
  41.     }  
  42.   
  43.     @Override  
  44.     public LocaleContext resolveLocaleContext(final HttpServletRequest request) {  
  45.         parseLocaleCookieIfNecessary(request);  
  46.         return new TimeZoneAwareLocaleContext() {  
  47.             @Override  
  48.             public Locale getLocale() {  
  49.                 return (Locale) request.getAttribute(LOCALE_REQUEST_ATTRIBUTE_NAME);  
  50.             }  
  51.             @Override  
  52.             public TimeZone getTimeZone() {  
  53.                 return (TimeZone) request.getAttribute(TIME_ZONE_REQUEST_ATTRIBUTE_NAME);  
  54.             }  
  55.         };  
  56.     }  
  57.     private void parseLocaleCookieIfNecessary(HttpServletRequest request) {  
  58.         if (request.getAttribute(LOCALE_REQUEST_ATTRIBUTE_NAME) == null) {  
  59.             // Retrieve and parse cookie value.  
  60.             Cookie cookie = WebUtils.getCookie(request, getCookieName());  
  61.             Locale locale = null;  
  62.             TimeZone timeZone = null;  
  63.             if (cookie != null) {  
  64.                 String value = cookie.getValue();  
  65.                 String localePart = value;  
  66.                 String timeZonePart = null;  
  67.                 int spaceIndex = localePart.indexOf(' ');  
  68.                 if (spaceIndex != -1) {  
  69.                     localePart = value.substring(0, spaceIndex);  
  70.                     timeZonePart = value.substring(spaceIndex + 1);  
  71.                 }  
  72.                 locale = (!"-".equals(localePart) ? StringUtils.parseLocaleString(localePart) : null);  
  73.                 if (timeZonePart != null) {  
  74.                     timeZone = StringUtils.parseTimeZoneString(timeZonePart);  
  75.                 }  
  76.                 if (logger.isDebugEnabled()) {  
  77.                     logger.debug("Parsed cookie value [" + cookie.getValue() + "] into locale '" + locale +  
  78.                             "'" + (timeZone != null ? " and time zone '" + timeZone.getID() + "'" : ""));  
  79.                 }  
  80.             }  
  81.             request.setAttribute(LOCALE_REQUEST_ATTRIBUTE_NAME,  
  82.                     (locale != null ? locale: determineDefaultLocale(request)));  
  83.             request.setAttribute(TIME_ZONE_REQUEST_ATTRIBUTE_NAME,  
  84.                     (timeZone != null ? timeZone : determineDefaultTimeZone(request)));  
  85.         }  
  86.     }  
  87.   
  88.     @Override  
  89.     public void setLocale(HttpServletRequest request, HttpServletResponse response, Locale locale) {  
  90.         setLocaleContext(request, response, (locale != null ? new SimpleLocaleContext(locale) : null));  
  91.     }  
  92.   
  93.     @Override  
  94.     public void setLocaleContext(HttpServletRequest request, HttpServletResponse response, LocaleContext localeContext) {  
  95.         Locale locale = null;  
  96.         TimeZone timeZone = null;  
  97.         if (localeContext != null) {  
  98.             locale = localeContext.getLocale();  
  99.             if (localeContext instanceof TimeZoneAwareLocaleContext) {  
  100.                 timeZone = ((TimeZoneAwareLocaleContext) localeContext).getTimeZone();  
  101.             }  
  102.             addCookie(response, (locale != null ? locale : "-") + (timeZone != null ? ' ' + timeZone.getID() : ""));  
  103.         }  
  104.         else {  
  105.             removeCookie(response);  
  106.         }  
  107.         request.setAttribute(LOCALE_REQUEST_ATTRIBUTE_NAME,  
  108.                 (locale != null ? locale: determineDefaultLocale(request)));  
  109.         request.setAttribute(TIME_ZONE_REQUEST_ATTRIBUTE_NAME,  
  110.                 (timeZone != null ? timeZone : determineDefaultTimeZone(request)));  
  111.     }  
  112.   
  113.     protected Locale determineDefaultLocale(HttpServletRequest request) {  
  114.         Locale defaultLocale = getDefaultLocale();  
  115.         if (defaultLocale == null) {  
  116.             defaultLocale = request.getLocale();  
  117.         }  
  118.         return defaultLocale;  
  119.     }  
  120.   
  121.     protected TimeZone determineDefaultTimeZone(HttpServletRequest request) {  
  122.         return getDefaultTimeZone();  
  123.     }  
  124.   
  125. }  
SessionLocaleResolver:与CookieLocaleResolver类似将语言信息放到Session中,这样整个系统就可以从Session中获得语言信息。

[java]  view plain  copy
 print ? 在CODE上查看代码片 派生到我的代码片
  1. public class SessionLocaleResolver extends AbstractLocaleContextResolver {  
  2.   
  3.     //语言信息放到session中的名称  
  4.     public static final String LOCALE_SESSION_ATTRIBUTE_NAME = SessionLocaleResolver.class.getName() + ".LOCALE";  
  5.   
  6.     public static final String TIME_ZONE_SESSION_ATTRIBUTE_NAME = SessionLocaleResolver.class.getName() + ".TIME_ZONE";  
  7.   
  8.   
  9.     @Override  
  10.     public Locale resolveLocale(HttpServletRequest request) {  
  11.         Locale locale = (Locale) WebUtils.getSessionAttribute(request, LOCALE_SESSION_ATTRIBUTE_NAME);  
  12.         if (locale == null) {  
  13.             locale = determineDefaultLocale(request);  
  14.         }  
  15.         return locale;  
  16.     }  
  17.   
  18.     @Override  
  19.     public LocaleContext resolveLocaleContext(final HttpServletRequest request) {  
  20.         return new TimeZoneAwareLocaleContext() {  
  21.             @Override  
  22.             public Locale getLocale() {  
  23.                 Locale locale = (Locale) WebUtils.getSessionAttribute(request, LOCALE_SESSION_ATTRIBUTE_NAME);  
  24.                 if (locale == null) {  
  25.                     locale = determineDefaultLocale(request);  
  26.                 }  
  27.                 return locale;  
  28.             }  
  29.             @Override  
  30.             public TimeZone getTimeZone() {  
  31.                 TimeZone timeZone = (TimeZone) WebUtils.getSessionAttribute(request, TIME_ZONE_SESSION_ATTRIBUTE_NAME);  
  32.                 if (timeZone == null) {  
  33.                     timeZone = determineDefaultTimeZone(request);  
  34.                 }  
  35.                 return timeZone;  
  36.             }  
  37.         };  
  38.     }  
  39.   
  40.     @Override  
  41.     public void setLocaleContext(HttpServletRequest request, HttpServletResponse response, LocaleContext localeContext) {  
  42.         Locale locale = null;  
  43.         TimeZone timeZone = null;  
  44.         if (localeContext != null) {  
  45.             locale = localeContext.getLocale();  
  46.             if (localeContext instanceof TimeZoneAwareLocaleContext) {  
  47.                 timeZone = ((TimeZoneAwareLocaleContext) localeContext).getTimeZone();  
  48.             }  
  49.         }  
  50.         WebUtils.setSessionAttribute(request, LOCALE_SESSION_ATTRIBUTE_NAME, locale);  
  51.         WebUtils.setSessionAttribute(request, TIME_ZONE_SESSION_ATTRIBUTE_NAME, timeZone);  
  52.     }  
  53.   
  54.     protected Locale determineDefaultLocale(HttpServletRequest request) {  
  55.         Locale defaultLocale = getDefaultLocale();  
  56.         if (defaultLocale == null) {  
  57.             defaultLocale = request.getLocale();  
  58.         }  
  59.         return defaultLocale;  
  60.     }  
  61.   
  62.     protected TimeZone determineDefaultTimeZone(HttpServletRequest request) {  
  63.         return getDefaultTimeZone();  
  64.     }  
  65.   
  66. }  

通过源码我们可以了解到springMVC对多语言的支持就是设置Locale的语言信息来实现的,只不过是设置了通过cookie、session等方式设置而已,接下来我们会通过demo来进一步介绍这几种实现方式。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值