struts2 国际化问题解决

在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的原理后,就好解决,我们现在要做的就是用用户自定义切换的国际化区域信息来替代浏览器请求报头里的语言信息。

先写一个过滤器,代码如下:
Java代码  收藏代码
  1. public class I18nFilter implements Filter {  
  2.   
  3.     @Override  
  4.     public void destroy() {  
  5.     }  
  6.   
  7.     @Override  
  8.     public void doFilter(ServletRequest req, ServletResponse resp,  
  9.             FilterChain filterChain) throws IOException, ServletException {  
  10.         HttpServletRequest r = (HttpServletRequest) req;  
  11.         MyRequestWrapper request = new MyRequestWrapper(r);  
  12.         filterChain.doFilter(request, resp);  
  13.     }  
  14. }  

配置为拦截所有请求
Java代码  收藏代码
  1. <filter>  
  2.         <filter-name>i18nFilter</filter-name>  
  3.         <filter-class>com.xxx.common.filter.I18nFilter</filter-class>  
  4.     </filter>  
  5.     <filter-mapping>  
  6.         <filter-name>i18nFilter</filter-name>  
  7.         <url-pattern>*</url-pattern>  
  8.     </filter-mapping>  


这个拦截器的关键就是使用httpRequestWrapper,保装request。
这个包装器代码如下:
Java代码  收藏代码
  1. public class MyRequestWrapper extends HttpServletRequestWrapper {  
  2.   
  3.     private Locale locale = null;  
  4.   
  5.     public MyRequestWrapper(HttpServletRequest request) {  
  6.         super(request);  
  7.         HttpSession session = request.getSession();  
  8.         locale = (Locale) session.getAttribute("WW_TRANS_I18N_LOCALE");  
  9.     }  
  10.   
  11.     /** 
  12.      * struts2的BUG,如果重定向的话,国际化默认取HTTP请求头中的参数 替换HTTP请求参数 
  13.      **/  
  14.     @Override  
  15.     public String getHeader(String name) {  
  16.         String value = super.getHeader(name);  
  17.         if ("Accept-Language".equals(name) && locale != null) {  
  18.             value = locale.getLanguage() + "_" + locale.getCountry()  
  19.                     + value.substring(6, value.length());  
  20.         }  
  21.         return value;  
  22.     }  
  23.   
  24.     @Override  
  25.     public Locale getLocale() {  
  26.         if (locale != null) {  
  27.             return locale;  
  28.         }  
  29.         return super.getLocale();  
  30.     }  
  31.   
  32. }  

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



  1. private static final String LANGUAGE="language";//application中key  
  2. //默认初始语言   或是  找用户计算机上的cookie信息  
  3.     public String getLanguage(){  
  4.         HttpServletRequest request=ServletActionContext.getRequest();  
  5.           
  6.         Cookie[] cookies= request.getCookies();  
  7.           
  8.         //cookie 中没有语言  默认从application取  
  9.         String language=ServletActionContext.getContext().getApplication().get(LANGUAGE).toString();  
  10.           
  11.         for(Cookie ck : cookies){  
  12.             if(ck.getName().equals(LANGUAGE)&&ck.getValue()!=null&&!"".equals(ck.getValue())){  
  13.                 logger.debug("cookie------->language:"+ck.getValue());  
  14.                 language=ck.getValue();  
  15.             }  
  16.         }  
  17.         logger.debug("----------->language:"+language);  
  18.           
  19.         ActionContext.getContext().setLocale(new Locale(language));  
  20.           
  21.         return language;  
  22.     }
  1. private static final String LANGUAGE="language";//application中key  
  2.     private String locale_language;//界面选择的语言  
  3.       
  4.     public String getLocale_language() {  
  5.         return locale_language;  
  6.     }  
  7.   
  8.     public void setLocale_language(String localeLanguage) {  
  9.         locale_language = localeLanguage;  
  10.     }  
  11. public String changeLanguage(){  
  12.         writeLanguage();  
  13.         return "success";  
  14.     }  
  15. //写cookie  
  16.     public void writeLanguage(){  
  17.         HttpServletResponse response=ServletActionContext.getResponse();  
  18.         Cookie cookie = new Cookie(LANGUAGE, locale_language);  
  19.         cookie.setMaxAge(356*24*60*60);  
  20.         response.addCookie(cookie);  
  21.     }  
  22. //默认初始语言   或是  找用户计算机上的cookie信息  
  23.     public String getLanguage(){  
  24.         HttpServletRequest request=ServletActionContext.getRequest();  
  25.           
  26.         Cookie[] cookies= request.getCookies();  
  27.           
  28.         //cookie 中没有语言  默认从application取  
  29.         String language=ServletActionContext.getContext().getApplication().get(LANGUAGE).toString();  
  30.           
  31.         for(Cookie ck : cookies){  
  32.             if(ck.getName().equals(LANGUAGE)&&ck.getValue()!=null&&!"".equals(ck.getValue())){  
  33.                 logger.debug("cookie------->language:"+ck.getValue());  
  34.                 language=ck.getValue();  
  35.             }  
  36.         }  
  37.         logger.debug("----------->language:"+language);  
  38.           
  39.         ActionContext.getContext().setLocale(new Locale(language));  
  40.           
  41.         return language;  
  42.     }


  • 1
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值