spring的国际化
2015-12-29 16:29
639 查看
一般客户端的语言特性,是通过cookie来传递的,也可以通过request的请求中获得locale的值。
先看CookieGenerator.java
这个地方就是response中回写cookie来存储locale的值。cookieName代表的是cookie的key值。如果我们采用的CookieLocaleResolver.java是本地的locale解析器。默认设置的cookieName是
继承自LocaleResolver的两个方法实现如下:
调用方法是DispatcherServlet.java中:
DispatcherServlet也包含其他的如上下文和主题等的生成。
初始化的时候指定对应的key值,对应到调用的地方是:
初始化本地化解析的方法调用如下:
spring的mvc拦截器会拦截客户端的请求来抓取到合适的locale解析器来获得locale的属性,从而通过resourceBundle来获得对应的属性文件里面的值。需要注意的点是bean的id需要设置成localeResolver。
分析一下i18n包下的几个类:
AcceptHeaderLocaleResolver --是获取请求头中的locale对象
CookieLocaleResolver --获取的是cookie中传递的locale对象,如果cookie 不存在,获取的也是请求头中的locale对象。其中默认的cookieName是:
是获取请求头中的locale对象,不同点是可以通过java代码来写入想要的locale对象。
上面只是spring的保持和传递locale对象的方式,也可以通过线程的方式来将locale绑定到ThreadLocale上面。来保持在一次请求过程中locale的值。取值的方式也可以参照前面的几种。
后续会加上ResourceBundle中调用的逻辑处理。
先看CookieGenerator.java
public void addCookie(HttpServletResponse response, String cookieValue) { Assert.notNull(response, "HttpServletResponse must not be null"); Cookie cookie = createCookie(cookieValue); Integer maxAge = getCookieMaxAge(); if (maxAge != null) { cookie.setMaxAge(maxAge); } if (isCookieSecure()) { cookie.setSecure(true); } if (isCookieHttpOnly()) { cookie.setHttpOnly(true); } response.addCookie(cookie); if (logger.isDebugEnabled()) { logger.debug("Added cookie with name [" + getCookieName() + "] and value [" + cookieValue + "]"); } }
这个地方就是response中回写cookie来存储locale的值。cookieName代表的是cookie的key值。如果我们采用的CookieLocaleResolver.java是本地的locale解析器。默认设置的cookieName是
public static final String DEFAULT_COOKIE_NAME = CookieLocaleResolver.class.getName() + ".LOCALE";
继承自LocaleResolver的两个方法实现如下:
public Locale resolveLocale(HttpServletRequest request) { // Check request for pre-parsed or preset locale. Locale locale = (Locale) request.getAttribute(LOCALE_REQUEST_ATTRIBUTE_NAME); if (locale != null) { return locale; } // Retrieve and parse cookie value. Cookie cookie = WebUtils.getCookie(request, getCookieName()); --批量在cookie中匹配对应key值的cookie if (cookie != null) { locale = StringUtils.parseLocaleString(cookie.getValue()); if (logger.isDebugEnabled()) { logger.debug("Parsed cookie value [" + cookie.getValue() + "] into locale '" + locale + "'"); } if (locale != null) { request.setAttribute(LOCALE_REQUEST_ATTRIBUTE_NAME, locale);--设置到request请求中,在spring的拦截器会使用时,拦截request时使用。 return locale; } } return determineDefaultLocale(request); --如果前面的cookie没有读取出来的话,读取的是request中包含的locale信息。 } public void setLocale(HttpServletRequest request, HttpServletResponse response, Locale locale) { if (locale != null) { // Set request attribute and add cookie. request.setAttribute(LOCALE_REQUEST_ATTRIBUTE_NAME, locale); --设置请求中的locale信息 addCookie(response, locale.toString()); --添加cookie到response中,设置到客户端中。 } else { // Set request attribute to fallback locale and remove cookie. request.setAttribute(LOCALE_REQUEST_ATTRIBUTE_NAME, determineDefaultLocale(request)); removeCookie(response); } }看一下拦截器对request的操作,是在类LocaleChangeInterceptor中引用:
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws ServletException { String newLocale = request.getParameter(this.paramName); --查看请求参数中是否有locale的参数名,感觉spring这个地方的处理略显粗糙了点 if (newLocale != null) { LocaleResolver localeResolver = RequestContextUtils.getLocaleResolver(request); --从spring的容器中获取localeResolver的实现 if (localeResolver == null) { throw new IllegalStateException("No LocaleResolver found: not in a DispatcherServlet request?"); } localeResolver.setLocale(request, response, StringUtils.parseLocaleString(newLocale)); } // Proceed in any case. return true; }接下来查看的是:
public static LocaleResolver getLocaleResolver(HttpServletRequest request) { return (LocaleResolver) request.getAttribute(DispatcherServlet.LOCALE_RESOLVER_ATTRIBUTE); --在请求的属性中是否有localeResolver的实现 }
调用方法是DispatcherServlet.java中:
public static final String LOCALE_RESOLVER_ATTRIBUTE = DispatcherServlet.class.getName() + ".LOCALE_RESOLVER";这里指定的是locale的解析类的key值。
DispatcherServlet也包含其他的如上下文和主题等的生成。
初始化的时候指定对应的key值,对应到调用的地方是:
protected void initStrategies(ApplicationContext context) { initMultipartResolver(context); initLocaleResolver(context); --初始化localeResolver initThemeResolver(context); initHandlerMappings(context); initHandlerAdapters(context); initHandlerExceptionResolvers(context); initRequestToViewNameTranslator(context); initViewResolvers(context); initFlashMapManager(context); }
初始化本地化解析的方法调用如下:
private void initLocaleResolver(ApplicationContext context) { try { this.localeResolver = context.getBean(LOCALE_RESOLVER_BEAN_NAME, LocaleResolver.class);//bean的值是localeResolver,定义bean值的时候需要bean的id为localeResolver. if (logger.isDebugEnabled()) { logger.debug("Using LocaleResolver [" + this.localeResolver + "]"); } } catch (NoSuchBeanDefinitionException ex) { // We need to use the default. this.localeResolver = getDefaultStrategy(context, LocaleResolver.class); //没找到时候采取的默认策略的localeResolver为org.springframework.web.servlet.i18n.AcceptHeaderLocaleResolver if (logger.isDebugEnabled()) { logger.debug("Unable to locate LocaleResolver with name '" + LOCALE_RESOLVER_BEAN_NAME + "': using default [" + this.localeResolver + "]"); } } }
spring的mvc拦截器会拦截客户端的请求来抓取到合适的locale解析器来获得locale的属性,从而通过resourceBundle来获得对应的属性文件里面的值。需要注意的点是bean的id需要设置成localeResolver。
分析一下i18n包下的几个类:
AcceptHeaderLocaleResolver --是获取请求头中的locale对象
CookieLocaleResolver --获取的是cookie中传递的locale对象,如果cookie 不存在,获取的也是请求头中的locale对象。其中默认的cookieName是:
public static final String DEFAULT_COOKIE_NAME = CookieLocaleResolver.class.getName() + ".LOCALE";SessionLocaleResolver --是从session中来获取的locale值,用会话来保持。默认的key值是:
public static final String LOCALE_SESSION_ATTRIBUTE_NAME = SessionLocaleResolver.class.getName() + ".LOCALE";FixedLocaleResolver --
是获取请求头中的locale对象,不同点是可以通过java代码来写入想要的locale对象。
上面只是spring的保持和传递locale对象的方式,也可以通过线程的方式来将locale绑定到ThreadLocale上面。来保持在一次请求过程中locale的值。取值的方式也可以参照前面的几种。
后续会加上ResourceBundle中调用的逻辑处理。
相关文章推荐
- Java 多线程:volatile 多线程同步关键字
- java判断时间间隔长度
- spring 将request body 转存...
- HashMap要点总结
- 【java】 java 中stop方法终止线程的不良后果
- 关于spring和springmvc使用过程中的问题帖(持续更新)
- 浅析Java中的final关键字
- 如何使用eclipse上传项目到git.osc
- Java多态性理解
- 为什么在eclipse中按F5调试进不到方法中
- Spark:用Scala和Java实现WordCount
- 各个浏览器下载乱码问题
- ERROR org.hibernate.proxy.pojo.javassist.JavassistProxyFactory 解决方法
- spring security 11种过滤器介绍
- Spring MVC过滤器-委派过滤器代理(DelegatingFilterProxy)
- Spring注解
- JAVA中的集合
- maven项目 误点Disable Maven Nature 变普通 java web项目
- Java 数据库操作
- Java类集学习(二)List接口