`
499490717
  • 浏览: 40507 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

struts2默认拦截器之i18n

阅读更多

在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国际化(i18n) :简单语言包的实现

    Struts2提供了一个内置拦截器`LocaleChangeInterceptor`,它可以监听请求参数,根据参数值改变当前的locale。 5. **HelloWorld示例**:`HelloWorld.jsp`是一个简单的例子,展示如何在Struts2中使用国际化。在页面上...

    Struts2默认拦截器解析.pdf

    Struts2是一个流行的Java web框架...总的来说,Struts2的默认拦截器提供了全面的功能支持,使得开发者能够构建安全、高效且易于维护的Web应用程序。理解并熟练掌握这些拦截器的使用,将有助于提升开发效率和应用质量。

    struts2 拦截器实例

    2. **默认拦截器栈**:`defaultStack`包含了Struts2内置的一些拦截器,如`params`(处理参数),`i18n`(处理国际化),`exception`(处理异常)等。 3. **应用全局拦截器**:现在,所有Action都会在执行前经过`...

    struts2 用拦截器 实现用户权限登录

    默认拦截器栈`defaultStack`包含了Struts2预定义的一些拦截器,如`params`、`i18n`等。在添加自定义拦截器时,可以将其插入到默认拦截器栈中,也可以创建自定义的拦截器栈。 ### 五、测试与优化 完成上述步骤后,你...

    struts2.X 拦截器源码

    `defaultStack`是Struts2提供的默认拦截器栈,包含了如`exception`、`params`、`i18n`等常用拦截器。 了解了拦截器的基本原理后,我们可以通过`Struts2.x 拦截器.avi`这个视频文件深入学习Struts2拦截器的实现细节...

    Struts2默认拦截器解析[归类].pdf

    以下是对Struts2默认拦截器的详细解析: 1. **AliasInterceptor** - 别名拦截器:允许为Action配置别名,使得同一个Action可以通过不同的URL访问。 2. **AutowiringInterceptor** - 自动装配拦截器:在Spring整合...

    Struts2 I18N国际化最简单例子

    在Struts2的配置文件`struts.xml`中,我们需要添加特定的拦截器`i18n`,它负责根据用户的浏览器设置自动选择相应的语言资源包。配置如下: ```xml &lt;interceptor name="i18n" class="org.apache.struts2....

    一个Struts2的核心拦截器例子

    - 使用`&lt;default-interceptor-ref&gt;`定义默认拦截器栈,所有未明确指定拦截器的动作都将使用这个栈。 4. **自定义拦截器**: - 创建一个新的Java类,实现`Interceptor`接口并重写`intercept()`方法。 - 在`...

    Struts2之拦截器原理分析及使用-上案例struts007

    Struts2还提供了一些内置的拦截器,如params(处理请求参数)、i18n(国际化支持)、exception(异常处理)等。这些拦截器极大地丰富了框架的功能,减少了开发者的工作量。 总的来说,Struts2的拦截器机制是其强大...

    struts2-i18n

    通过结合使用Struts2的拦截器(interceptors)和自定义标签,可以构建出强大的国际化功能,满足各种复杂需求。 总之,Struts2-i18n为开发者提供了便捷的手段,帮助他们构建全球化Web应用。通过合理的资源文件管理和...

    struts2拦截器原理

    在这个例子中,`defaultStack`是Struts2默认提供的拦截器栈,包含了一些基础的拦截器,如`params`(处理请求参数)、`i18n`(国际化)等。`myCustomInterceptor`则是我们自定义的拦截器。 创建自定义拦截器有三种...

    struts2拦截器国际化

    在Struts2中,拦截器(Interceptor)是实现业务逻辑控制和增强功能的重要机制,而国际化(Internationalization,简称i18n)则能帮助我们构建支持多语言的Web应用。下面将详细解释这两个知识点以及它们如何在Struts2...

    Struts2 拦截器的执行顺序(二十九)

    通过分析这些源代码,我们可以了解自定义拦截器的实现方式以及与默认拦截器如何协同工作。 而`WebRoot`目录则包含了Web应用的静态资源,如HTML、CSS、JavaScript文件,以及Struts2的配置文件(如`struts.xml`)和...

    struts2内置拦截器简介

    ### Struts2内置拦截器简介 Struts2框架在实现MVC模式时,为了更好地管理请求处理过程中的各个阶段,引入了拦截器机制。通过拦截器可以对请求进行预处理或后处理,使得代码更加模块化和易于维护。Struts2提供了一...

    struts2-拦截器.docx

    - **默认拦截器**:Struts2提供了一些内置的拦截器,比如`params`用于处理请求参数,`exception`用于异常处理,`i18n`处理国际化,`validation`执行字段验证等。这些默认拦截器的配置可以在`struts-default.xml`文件...

    Struts 2的拦截器

    Struts2 拦截器是该框架的核心组件之一,主要负责在Action执行前后插入额外的功能处理。拦截器是基于Java的动态代理机制实现的,它允许开发者在不修改Action类本身的情况下,增加新的功能或者改变Action的行为。下面...

    Struts2 拦截器-v3

    3. **默认拦截器**:Struts2框架提供了许多内置拦截器,如`params`(处理请求参数)、`validation`(进行表单验证)、`i18n`(国际化支持)等。理解并熟练使用这些默认拦截器是基础。 4. **自定义拦截器**:当默认...

    12 struts2拦截器

    Struts2提供了一系列内置的拦截器,如`params`拦截器用于处理请求参数,`exception`拦截器处理异常,`i18n`拦截器实现国际化,`chain`拦截器使请求继续执行下一个Action,`timer`记录Action的执行时间等。这些拦截...

    [原]Struts2-拦截器

    我们可以在`&lt;package&gt;`元素内使用`&lt;interceptors&gt;`和`&lt;interceptor&gt;`标签来定义拦截器,并使用`&lt;default-interceptor-ref&gt;`来指定默认拦截器栈。例如,我们可以创建一个名为`loggingInterceptor`的拦截器,然后在...

    Struts2拦截器

    5. **默认拦截器栈** - Struts2提供了一个默认的拦截器栈(`defaultStack`),它包含了诸如`params`(处理请求参数)、`i18n`(国际化处理)等预定义的拦截器。在Action配置中,通过`...

Global site tag (gtag.js) - Google Analytics