在struts2的struts-default.xml中定义了一个name为i18n拦截器,实现类是com.opensymphony.xwork2.interceptor.I18nInterceptor,它的作用是根据用户请求设置session的语言环境。该拦截器有三个参数,parameterName,requestOnlyParameterName,attributeName;前两个是设置用户语言环境参数的name值,最后一个是设置session中保存语言环境对象的key值;三者的默认值分别为:request_locale,request_only_locale,WW_TRANS_I18N_LOCALE(后续讨论中将使用默认值)。用户请求中request_locale参数的优先级大于request_only_locale,语言环境是从request_locale参数中获得,该语言环境对象将会以key值为WW_TRANS_I18N_LOCALE保存到session中,语言环境是从request_only_locale总获得,设置值在当前请求中起效。请求中不存在request_locale和request_only_locale参数,将会从session中获取key值为WW_TRANS_I18N_LOCALE的对象,若该对象为null或者不是Locale类型,将使用ActionContext.getLocale()方法获取语言环境。当执行完以上一系列逻辑后,将会把当前上下文的语言环境设置为获取到的对象。以上逻辑的代码如下:
public String intercept(ActionInvocation invocation) throws Exception { if (LOG.isDebugEnabled()) { LOG.debug("intercept '" + invocation.getProxy().getNamespace() + "/" + invocation.getProxy().getActionName() + "' { "); } //get requested locale Map<String, Object> params = invocation.getInvocationContext().getParameters(); boolean storeInSession = true; Object requested_locale = findLocaleParameter(params, parameterName); if (requested_locale == null) { requested_locale = findLocaleParameter(params, requestOnlyParameterName); if (requested_locale != null) { storeInSession = false; } } //save it in session Map<String, Object> session = invocation.getInvocationContext().getSession(); Locale locale = null; if (requested_locale != null) { locale = (requested_locale instanceof Locale) ? (Locale) requested_locale : LocalizedTextUtil.localeFromString(requested_locale.toString(), null); } if (session != null) { synchronized (session) { if (locale == null) { storeInSession = false; // check session for saved locale Object sessionLocale = session.get(attributeName); if (sessionLocale != null && sessionLocale instanceof Locale) { locale = (Locale) sessionLocale; } else { // no overriding locale definition found, stay with current invocation (=browser) locale locale = invocation.getInvocationContext().getLocale(); } } if (storeInSession) { session.put(attributeName, locale); } } } saveLocale(invocation, locale); final String result = invocation.invoke(); return result; }
笔者之前有个项目需要添加国际化功能,固定支持某几种语言,当系统不支持请求中的语言环境时,需要设置为项目配置的默认语言环境,因此笔者写了一个struts2的拦截器来完成,代码如下:
import java.util.Locale; import java.util.Map; import org.apache.struts2.ServletActionContext; import com.opensymphony.xwork2.ActionInvocation; import com.opensymphony.xwork2.interceptor.AbstractInterceptor; import com.opensymphony.xwork2.interceptor.I18nInterceptor; import com.opensymphony.xwork2.util.LocalizedTextUtil; import com.warning.system.Constants; import com.warning.system.lang.WarningLogger; /** * 为struts2配置语言环境 * */ @SuppressWarnings("serial") public class DefaultLanguageInterceptor extends AbstractInterceptor { private static WarningLogger log = WarningLogger .getWarningLogger(DefaultLanguageInterceptor.class); @SuppressWarnings("unchecked") @Override public String intercept(ActionInvocation invocation) throws Exception { Locale locale = null; // 获取request的参数列表 Map<String, Object> params = ServletActionContext.getRequest() .getParameterMap(); // 获取session Map<String, Object> session = invocation.getInvocationContext() .getSession(); // 获取request中request_locale参数值 Object requested_locale = findLocaleParameter(params, I18nInterceptor.DEFAULT_PARAMETER); log.debug("获取request Parameter中的" + I18nInterceptor.DEFAULT_PARAMETER + "参数值"); // 如果request中request_locale参数值为null,则获取request_only_locale参数值 if (requested_locale == null) { log.debug("request Parameter中不存在" + I18nInterceptor.DEFAULT_PARAMETER + "参数值"); log.debug("获取request Parameter中的" + I18nInterceptor.DEFAULT_REQUESTONLY_PARAMETER + "参数值"); requested_locale = findLocaleParameter(params, I18nInterceptor.DEFAULT_REQUESTONLY_PARAMETER); // 如果request中request_only_locale参数值为null,则从session中获取WW_TRANS_I18N_LOCALE值,该值是struts2 // 框架中的i18n拦截器根据request的request_locale参数值设置的语言环境 if (requested_locale == null) { log .debug("request Parameter中不存在" + I18nInterceptor.DEFAULT_REQUESTONLY_PARAMETER + "参数值"); log.debug("获取session中的" + I18nInterceptor.DEFAULT_SESSION_ATTRIBUTE + "参数值"); requested_locale = session .get(I18nInterceptor.DEFAULT_SESSION_ATTRIBUTE); // 如果session中不存在WW_TRANS_I18N_LOCALE值,则获取ActionContext的语言环境 if (requested_locale == null) { log .debug("session中不存在" + I18nInterceptor.DEFAULT_SESSION_ATTRIBUTE + "参数值"); log.debug("获取ActionContext中的Locale值"); requested_locale = invocation.getInvocationContext() .getLocale(); } } } // 如果requested_locale为null,则将locale设置为国际化资源文件(config.properties.language)中配置的(warning.language.default)默认语言环境; // 如果requested_locale类型为Locale,则直接赋值给locale; // 如果上述两项都不匹配,则根据requested_locale初始化一个Locale对象 locale = (requested_locale instanceof Locale) ? (Locale) requested_locale : (requested_locale != null ? LocalizedTextUtil .localeFromString(requested_locale.toString(), Constants.getLanguages().getDefaultLocale()) : Constants.getLanguages().getDefaultLocale()); // 如果国际化资源文件中配置的语言环境不包含上述获取的语言环境,则将locale赋值为国际化资源文件中配置的默认语言环境 if (!Constants.getLanguages().getLocales().containsValue(locale)) { log.info("国际化资源文件中配置的语言环境不包含 " + locale + ",将locale赋值为配置的默认语言"); locale = Constants.getLanguages().getDefaultLocale(); } // 设置ActionContext的语言环境 log.info("将struts2的语言环境设置为:" + locale); invocation.getInvocationContext().setLocale(locale); return invocation.invoke(); } /** * 从Map集合中获取指定元素的值 * * @param params * @param parameterName * @return */ private Object findLocaleParameter(Map<String, Object> params, String parameterName) { Object requested_locale = params.get(parameterName); if (requested_locale != null && requested_locale.getClass().isArray() && ((Object[]) requested_locale).length == 1) { requested_locale = ((Object[]) requested_locale)[0]; } return requested_locale; } }
struts2配置文件内容如下:
<package name="warning-default" extends="struts-default" abstract="true"> <interceptors> <interceptor name="defaultLanguage" class="com.warning.module.language.interceptor.DefaultLanguageInterceptor" /> <interceptor-stack name="warningDefaultStack"> <interceptor-ref name="defaultStack" /> <interceptor-ref name="defaultLanguage" /> </interceptor-stack> </interceptors> <default-interceptor-ref name="warningDefaultStack" /> <global-results> <result name="login">/WEB-INF/jsp/sys/login.jsp</result> </global-results> </package>
设置完成后,运行项目,将浏览器语言环境设置为系统不支持的一种,然后访问页面,奇迹出现了,页面中竟然出现了两种语言……笔者以为是上面的拦截器逻辑出现了错误,将代码审查了一遍发现没有错误,正在纠结的时候突然灵光一现,发现struts2配置中的默认拦截器defaultStack在defaultLanguage之前,
这样将会先执行默认拦截器栈中的各个拦截器,然后才会执行笔者定义的拦截器defaultLanguage,将两者位置调换
<package name="warning-default" extends="struts-default" abstract="true"> <interceptors> <interceptor name="defaultLanguage" class="com.warning.module.language.interceptor.DefaultLanguageInterceptor" /> <interceptor-stack name="warningDefaultStack"> <interceptor-ref name="defaultLanguage" /> <interceptor-ref name="defaultStack" /> </interceptor-stack> </interceptors> <default-interceptor-ref name="warningDefaultStack" /> <global-results> <result name="login">/WEB-INF/jsp/sys/login.jsp</result> </global-results> </package>
重新运行项目,访问,奇迹再一次发生了,页面中的信息全部成为了项目的默认语言。为什么调换一下两个拦截器的位置就可以了呢,原因在于执行默认拦截器栈中的拦截器时,语言环境尚未设置为项目默认的语言环境,拦截器栈中的各拦截器会根据当前语言环境去获取国际化资源,当执行了defaultLanguage拦截器,系统语言环境变成了项目默认语言环境,
这样在页面中会根据项目默认语言环境来获取国际化资源,便出现了页面中存在两种语言的情况。
但如果用户请求中request_locale或者request_only_locale参数值对应语言环境是项目不支持的,那么页面中还会出现两种语言的情况,因此需要根据笔者上述的拦截器逻辑来重写i18n拦截器。
版权所有,转载请标明出处:http://blogwarning.iteye.com/blog/1336685
发表评论
-
struts2默认拦截器之chain
2012-05-08 22:32 941在struts2的struts-default.xml中定义了 ... -
struts2默认拦截器之prepare
2012-02-02 11:26 8200在struts2的struts-default.xml中定义 ... -
struts2默认拦截器之servletConfig
2012-01-06 11:46 2438在struts2的struts-default.xml中定义 ... -
struts2默认拦截器之exception
2012-01-04 11:26 5933在struts2的struts-default.xml ... -
struts2默认拦截器之autowiring
2011-12-31 16:30 3394在struts2的struts-defaul ... -
struts2默认拦截器之alias
2011-12-31 16:17 3292在struts2的struts- ...
相关推荐
struts2国际化_i18n 完整实例。欢迎下载。
Struts2拦截器(Interceptor) Struts2拦截器(Interceptor)
Struts2默认拦截器解析.pdf
解决Struts2中的中文乱码。该代码是用作Struts2的拦截器中
struts2 国际化 i18n struts2 国际化 i18n struts2 国际化 i18n
Struts2默认拦截器解析[归类].pdf
该例子为struts2注解与拦截器demo,利用myEclipse8.5开发,导入刚才后,自动加载所需struts2的jar包,可以直接运行,是初学struts2注解、拦截器很好的例子,保证10分钟学会2种技术,愿意分享给大家。
struts2常用拦截器,struts2经常用到的拦截器,熟悉熟悉
NULL 博文链接:https://blogwarning.iteye.com/blog/1390172
用MyEclipse工具实现的一个struts2国际化,用于刚接解struts2中i18n的同学学习。很好的代码,深入浅出。
struts2 Interceptor拦截器 http://whitewolf.0fees.net
使用Struts2实现用户权限拦截、重点是掌握拦截器的使用和配置方法,通过案例的学习,就能掌握struts中拦截器的使用方法,让我们能快速上手
Struts2拦截器.ppt Struts2拦截器.ppt Struts2拦截器.ppt
关于struts2 拦截器的详细的解释及其在开发中对struts2的拦截器的应用和拦截器在框架中的作用.
详细说明了struts2中拦截器的使用。并且通过一个小例子讲解了拦截器的具体使用
Struts2拦截器源程序 Struts2拦截器源程序 Struts2拦截器源程序 Struts2拦截器源程序 Struts2拦截器源程序
Struts2的国际化的详细讲解 truts2的国际化与Struts1.2不太一样,对于我们一般的应用程序来说是非常重要的,因为它只需要我们来开发一套逻辑,可以以多种语言来显示,Struts2的国际化本身是基于JAVA语言的国际化的...
struts2,Interceptor struts2拦截器实例,两套实例,一套是针对单个的action配置的,另一套实例是针对全局的action配置的拦截器interceptor
struts2 用拦截器 实现用户权限登录 可以直接运行,只单单用到struts的东西。
struts2拦截器应用小例子,与大家共分享