`
showtime520
  • 浏览: 87441 次
  • 性别: Icon_minigender_1
  • 来自: 湖南
社区版块
存档分类
最新评论

STRUTS 2 国际化并自定义切换语言的问题解决

    博客分类:
  • JAVA
阅读更多
在struts2配置文件struts.xml中添加好国际化拦截器,struts。properties中指定好资源文件后(这2步网上一搜一大把,就不再写),项目的国际化就弄好了。现在把浏览器的语言改成其他语言能顺利国际化访问。

  这一步做好后,我们开始要做自定义国际化切换的功能。这个功能网上搜到的内容都是错误,所以特此在此记录下,以方便后来人。
  网上很多说自定义国际化切换只要修改保存在session中的struts2国际化常量的值“WW_TRANS_I18N_LOCALE”就行了。
  实际上时完全错误,我们先看看struts2国际化的步骤:

    1、判断struts.locale属性(在struts.properties)是否有值,如果有值,将这个值转换为Locale对象保存到ActionContext中。
    2、如果没有设置struts.locale,从浏览器发送的请求报头里获得语言信息,创建Locale对象,保存到ActionContext中。
    3、I18nInterceptor拦截器获取名为request_locale请求参数的值,如果这个值存在则创建以这个值的Locale对象,然后将这个对象作为session的属性(WW_TRANS_I18N_LOCALE)保存,并保存到ActionContext中。


在修改session的WW_TRANS_I18N_LOCALE值和request_locale等无效之后,发现程序始终是只会读取浏览器发送过来的区域信息。估计这是struts2国际化得BUG了。

知道了struts2的原理后,就好解决,我们现在要做的就是用用户自定义切换的国际化区域信息来替代浏览器请求报头里的语言信息。

先写一个过滤器,代码如下:
public class I18nFilter implements Filter {

	@Override
	public void destroy() {
	}

	@Override
	public void doFilter(ServletRequest req, ServletResponse resp,
			FilterChain filterChain) throws IOException, ServletException {
		HttpServletRequest r = (HttpServletRequest) req;
		MyRequestWrapper request = new MyRequestWrapper(r);
		filterChain.doFilter(request, resp);
	}
}

配置为拦截所有请求
<filter>
		<filter-name>i18nFilter</filter-name>
		<filter-class>com.xxx.common.filter.I18nFilter</filter-class>
	</filter>
	<filter-mapping>
		<filter-name>i18nFilter</filter-name>
		<url-pattern>*</url-pattern>
	</filter-mapping>


这个拦截器的关键就是使用httpRequestWrapper,保装request。
这个包装器代码如下:
public class MyRequestWrapper extends HttpServletRequestWrapper {

	private Locale locale = null;

	public MyRequestWrapper(HttpServletRequest request) {
		super(request);
		HttpSession session = request.getSession();
		locale = (Locale) session.getAttribute("WW_TRANS_I18N_LOCALE");
	}

	/**
	 * struts2的BUG,如果重定向的话,国际化默认取HTTP请求头中的参数 替换HTTP请求参数
	 **/
	@Override
	public String getHeader(String name) {
		String value = super.getHeader(name);
		if ("Accept-Language".equals(name) && locale != null) {
			value = locale.getLanguage() + "_" + locale.getCountry()
					+ value.substring(6, value.length());
		}
		return value;
	}

	@Override
	public Locale getLocale() {
		if (locale != null) {
			return locale;
		}
		return super.getLocale();
	}

}

这个request包装器主要作用就是从session里获得区域对象,并修改请求报头,从而实现了自定义国际化切换。

如果本方法有问题或者各位有更好的方法,请告知。谢谢
分享到:
评论
2 楼 zhou363667565 2011-07-30  
我把整个流程代码都贴出来   帮帮我  解决!

界面请求Code:

<select name="request_locale" onchange="changeLanguage(this)">
		 						<option value="-1">please select...</option>
		 						<option value="zh_CN">Chinese(Simplified)</option>
		 						<option value="zh_TW">Chinese(Traditional)</option>
		 						<option value="en_US">English(US)</option>
		 						<option value="en">English</option>
		 					</select>

js  Code:
//修改语言
function changeLanguage(obj){
	var url="/wmba/userLoginAction/userLoginAction_changeLanguage.action?locale_language="+obj.value+"&request_locale="+obj.value;
	window.parent.location=url;
}


struts2 Code:
private static final String LANGUAGE="language";//application中key
	private String locale_language;//界面选择的语言
	
	public String getLocale_language() {
		return locale_language;
	}

	public void setLocale_language(String localeLanguage) {
		locale_language = localeLanguage;
	}
public String changeLanguage(){
		writeLanguage();
		return "success";
	}
//写cookie
	public void writeLanguage(){
		HttpServletResponse response=ServletActionContext.getResponse();
		Cookie cookie = new Cookie(LANGUAGE, locale_language);
		cookie.setMaxAge(356*24*60*60);
		response.addCookie(cookie);
	}
//默认初始语言   或是  找用户计算机上的cookie信息
	public String getLanguage(){
		HttpServletRequest request=ServletActionContext.getRequest();
		
		Cookie[] cookies= request.getCookies();
		
		//cookie 中没有语言  默认从application取
		String language=ServletActionContext.getContext().getApplication().get(LANGUAGE).toString();
		
		for(Cookie ck : cookies){
			if(ck.getName().equals(LANGUAGE)&&ck.getValue()!=null&&!"".equals(ck.getValue())){
				logger.debug("cookie------->language:"+ck.getValue());
				language=ck.getValue();
			}
		}
		logger.debug("----------->language:"+language);
		
		ActionContext.getContext().setLocale(new Locale(language));
		
		return language;
	}

没有其它拦截器什么的!只用到了你的那两个类。登陆成功之后就会调用getlanguage()方法,跳转到主界面。还有:有什么好方法让登陆的页面也改变成cookie中语言啊!
1 楼 zhou363667565 2011-07-30  
很强大,正好是我所需要的!我copy了你的代码,试了一下,确实已经达到了自定义切换语言的效果!  我现在的需求是:用户选择语言,保存到用户的计算机中(cookie),以后只要用户不选择语言,默认读取cookie中的语言。现在遇到的问题:打开浏览器登陆之后主界面又回到了浏览器的语言!
struts2:
private static final String LANGUAGE="language";//application中key
//默认初始语言   或是  找用户计算机上的cookie信息
	public String getLanguage(){
		HttpServletRequest request=ServletActionContext.getRequest();
		
		Cookie[] cookies= request.getCookies();
		
		//cookie 中没有语言  默认从application取
		String language=ServletActionContext.getContext().getApplication().get(LANGUAGE).toString();
		
		for(Cookie ck : cookies){
			if(ck.getName().equals(LANGUAGE)&&ck.getValue()!=null&&!"".equals(ck.getValue())){
				logger.debug("cookie------->language:"+ck.getValue());
				language=ck.getValue();
			}
		}
		logger.debug("----------->language:"+language);
		
		ActionContext.getContext().setLocale(new Locale(language));
		
		return language;
	}


用户登录成功就调用该方法,行不通....很郁闷!  求解啊!

相关推荐

    Struts2 in action中文版

    11.1.2 Struts 2如何解决本地Java对i18n支持的问题 243 11.2 Struts 2 i18n示例 244 11.2.1 Struts 2 i18n快速展示 244 11.2.2 幕后一览 246 11.3 Struts 2 i18n详情 247 11.3.1 Struts 2默认的TextProvider Re-...

    Struts2 学习笔记

    01 Struts2-Action 5 一、 Struts作用: 5 二、 搭建Struts2的运行环境: 5 三、 Namespace 6 四、 标签 6 五、 Action 6 ...五、 国际化-动态语言切换 37 09 自定义拦截器 38 10 类型转换 38 Struts2总结 39

    Struts2帮助```````

    01 Struts2-Action 5 一、 Struts作用: 5 二、 搭建Struts2的运行环境: 5 三、 Namespace 6 四、 标签 6 五、 Action 6 ...五、 国际化-动态语言切换 37 09 自定义拦截器 38 10 类型转换 38 Struts2总结 39

    低清版 大型门户网站是这样炼成的.pdf

    2.4.3 struts 2国际化语言的动态切换 89 2.5 struts 2的校验框架 90 2.5.1 在action中实现手动校验 90 2.5.2 调用校验框架进行自动校验 91 2.5.3 自定义国际化struts 2校验错误消息 92 2.5.4 struts 2的自带...

    Maven2 的新特性.7z

    幸运的是,Maven2一出现就备受关注,要不了多长时间,诸如此类的问题应该就会很快解决。 回页首 结论 Maven2在Maven1的优势基础之上,又向前迈进了一大步。它提供的这些新特性大大地缩短了开发管理中的...

    JAVA上百实例源码以及开源项目源代码

    6个目标文件,EJB来模拟银行ATM机的流程及操作:获取系统属性,初始化JNDI,取得Home对象的引用,创建EJB对象,并将当前的计数器初始化,调用每一个EJB对象的count()方法,保证Bean正常被激活和钝化,EJB对象是用...

    JAVA上百实例源码以及开源项目

    6个目标文件,EJB来模拟银行ATM机的流程及操作:获取系统属性,初始化JNDI,取得Home对象的引用,创建EJB对象,并将当前的计数器初始化,调用每一个EJB对象的count()方法,保证Bean正常被激活和钝化,EJB对象是用...

    java项目之hrm人事管理项目(java毕业设计)

    2、后台:Struts2、动态代理、Mybatis框架、log4J日志框架、jstl 、jstl自定义分页标签、代码机器人、Dwr、POI(实现Excel文件的导入导出)等 3、数据库:Mysql 4、服务器:Tomcat 项目中涉及的功能: 1、项目以及...

Global site tag (gtag.js) - Google Analytics