I18nInterceptor

该拦截器处理defaultStack第四的位置,是用来方便国际化的,如果说我们的一个Web项目要支持国际化的话,通常的做法是给定一个下拉框列出所支持的语言,当用户选择了一种语言后后面浏览的所有页面自动切换到所选择的语言版本,而该拦截器就是用来实现该功能的。要实现语言切换说白了就是动态改变Locale。

在该拦截器中定义了三个属性,分别是:parameterName,requestOnlyParameterName,attributeName,这三个属性都有默认值,相应地分别是:"request_locale","request_only_locale","WW_TRANS_I18N_LOCALE",当然可以手动地给该拦截器传递参数以改变这几个属性的值。第一个属性的指的是切换Locale时指定的request参数名称并且要把Locale存储到session中,第二个参数与第一个意思一样只不过不存储到session中,只对当前request有效,第三个参数指的是存储到session中的Locale的key。下面看一下该拦截器是如何实现该功能的:

@Override
public String intercept(ActionInvocation invocation) throws Exception {
//省略...
//获取请求参数
Map<String, Object> params = invocation.getInvocationContext().getParameters(); boolean storeInSession = true;//是否要把Locale存在session中的开关变量
Object requested_locale = findLocaleParameter(params, parameterName);
if (requested_locale == null) {//无request_locale参数
requested_locale = findLocaleParameter(params, requestOnlyParameterName);
if (requested_locale != null) {//有request_only_locale参数
storeInSession = false;//是request_only_locale则不存储在session中
}
} //获取session Map
Map<String, Object> session = invocation.getInvocationContext().getSession(); Locale locale = null;
if (requested_locale != null) {//请求参数中有request_locale或request_only_locale
//将字符串转化为Locale对象
locale = (requested_locale instanceof Locale) ?
(Locale) requested_locale : LocalizedTextUtil.localeFromString(requested_locale.toString(), null);
//省略...
}
if (session != null) {
synchronized (session) {
if (locale == null) {//如果请求参数中即没有request_locale也没有request_only_locale
// check session for saved locale
Object sessionLocale = session.get(attributeName);//如果session中已经有Locale对象
if (sessionLocale != null && sessionLocale instanceof Locale) {
locale = (Locale) sessionLocale;//把session中的Locale对象获取出来
//省略...
} else {//如果session中也没有Locale对象
// no overriding locale definition found, stay with current invokation (=browser) locale
locale = invocation.getInvocationContext().getLocale();//则获取ActionContext中的Locale
//省略...
storeInSession = false;//并且不存储到session中
}
}
if (storeInSession) {//如果storeInSession为true则把Locale存储到Session中
session.put(attributeName, locale);
}
}
}
saveLocale(invocation, locale);//将Locale存储到ActionContext中
//省略...
return result;
}
//从请求参数中获取Locale字符串值
private Object findLocaleParameter( Map<String, Object> params, String parameterName ) {
Object requested_locale = params.remove(parameterName);
if (requested_locale != null && requested_locale.getClass().isArray()
&& ((Object[]) requested_locale).length == 1) {
requested_locale = ((Object[]) requested_locale)[0];
}
return requested_locale;
}
//将Locale对象存储到ActionContext中
protected void saveLocale(ActionInvocation invocation, Locale locale) {
invocation.getInvocationContext().setLocale(locale);
}

为了更集中于功能实现,上面的方法中省略了日志if判断,如果要看完整源码请参看struts2自带源码。

   sturts2是根据ActionContext中的Locale对象去找相应的国际化资源文件的,所以要动态切换语言版本就是要动态改变ActionContext中的Locale对象,intercept方法中的执行逻辑上面的注释已经写得清楚了,这里列举一下传递request参数时可能出现的情况:

1.只传递request_locale参数,该拦截器就会将该参数值转成一个Locale对象,然后以"WW_TRANS_I18N_LOCALE"为吸存储到session中,并且更新ActionContext中的Locale对象,这样如果在以后的请求参没有传递request_locale参数,这时session中已经有了Locale对象,那么该拦截器就会将session中的Locale对象更新到ActionContext中,这样就可以实现语言的切换了。

2.只传递request_only_locale对数,这种情况下Locale对象不会存储到session中,在该次请求能将传递的Locale更新到ActionContext中因为没有存储到session中,在以后的请求中如果没有传递request_only_locale或request_locale,那么被更新到ActionContext中Locale

还是ActionContext原先的Locale,这样又回到了原来的语言版本。

3.request_locale与request_only_locale都没有传递,这种情况不用解释。

更新完ActionContext中的Locale对象后,调用下一个拦截器......

最新文章

  1. 中控考勤仪IFace302多线程操作时无法订阅事件
  2. Game of Life I &amp; II
  3. Python 的字符串格式化和颜色控制
  4. 让我们一起学习《Node.js入门》一书吧!
  5. SQL Server 2005 中的同义词
  6. HDU-5785 Interesting(Manacher算法+区间处理)
  7. 一个坐标点围绕任意中心点旋转--C#实现
  8. 关于Qt在子线程中使用QMessageBox的折衷方法
  9. Android APK反编译就这么简单 详细解释(简介)
  10. Hibernate 系列教程1-枚举单例类
  11. A workaround to change shared memory size for Docker containers in AWS ECS
  12. Elasticsearch: 权威指南 &#187; 深入搜索 &#187; 多字段搜索 &#187; 多数字段 good
  13. 金蝶CLOUD与EAS的区别
  14. [Bayes] prod: M-H: Independence Sampler for Posterior Sampling
  15. python 正则基本方法
  16. MySQL数据库InnoDB存储引擎
  17. strcpy,memcpy,memset函数实现
  18. OpenMP 《并行程序设计导论》的补充代码
  19. codeforces765F Souvenirs
  20. java 代码块的执行顺序

热门文章

  1. Codeforces.547C.Mike and Foam(容斥/莫比乌斯反演)
  2. [UOJ430]line
  3. python开发_tkinter_自己做的猜数字小程序
  4. PAT甲级1114. Family Property
  5. asp.net 判断日期是否为空
  6. 如何使用mysql存储树形关系
  7. Git_添加远程库
  8. 客户端程序获取自己的ip、isp、地理位置等信息
  9. CentOS 7提示:ERROR unsupported format character &#39;(0xffffffe7) at/域安装失败,您可以运行下列命令重启您的域:
  10. ESB的几个基本概念