JSF1.2 中实现国际化

JSF的<f:view>标签中可以通过locale属性来指定语言和区域信息来实现国际化,如:<f:view locale="#{indexBean.locale}">。
在实践中发现这个属性不起作用,后台IndexBean的locale已经改变,但是前台界面显示的语言没有跟这变化。
简单的跟踪一下代码发现大致的原因如下:

以index.jsp为例来说明:

1、第一次打开index.jsp页面,系统创建一个UIViewRoot对象,根据#{indexBean.locale}(默认为zh_CN)设置UIViewRoot对象locale值,这种情况下页面显示是正确。
2、在页面通过按钮或者选择列表改变#{indexBean.locale}的值为"en_US",按照设想页面显示的语言应该为英文,但实际情况还是中文。
  
   跟踪代码发现问题在UIComponentClassicTagBase.java的findComponent()方法中

      //获取UIViewRoot对象

      parentComponent = context.getViewRoot();

      if (null == parentComponent.getAttributes().get("javax.faces.webapp.CURRENT_VIEW_ROOT"))
      {
        try
        {
          //这个方法里面会用#{indexBean.locale}的值来设置UIViewRoot对象locale值
          //第一次打开index.jsp时,UIViewRoot对象是新建的所以parentComponent.getAttributes().get("javax.faces.webapp.CURRENT_VIEW_ROOT")==null
          //执行此方法。当通过通过触发页面上的按钮或者下拉列表重新绘制index.jsp时,由于JSF会保存的组件的状态而且可以恢复,此时的 UIViewRoot对象还是上次
          //创建的对象,所以 parentComponent.getAttributes().get("javax.faces.webapp.CURRENT_VIEW_ROOT")==null 这个条件不满足,因此也不会执行此方法。

          setProperties(parentComponent);
        }
        catch (FacesException e) {
          if (e.getCause() instanceof JspException) {
            throw ((JspException)e.getCause());
          }
          throw e;
        }

        if (null != this.id) {
          parentComponent.setId(this.id);
        }
        else {
          assert (null != getFacesJspId());
          parentComponent.setId(getFacesJspId());
        }
        parentComponent.getAttributes().put("javax.faces.webapp.CURRENT_VIEW_ROOT", "javax.faces.webapp.CURRENT_VIEW_ROOT");

        this.created = true;
      }
      else if (hasBinding()) {
        try {
          setProperties(parentComponent);
        }
        catch (FacesException e) {
          if (e.getCause() instanceof JspException) {
            throw ((JspException)e.getCause());
          }
          throw e;
        }

      } 
 


3、这个问题在MyFaces中没有发现,不知道是参考实现中的BUG还是使用方法的错误。

4、一个替代的解决方法是加入一个PhaseListener,然后在PhaseId.RENDER_RESPONSE之前直接调用UIViewRoot对象的setLocale方法来改变语言和区域信息。
    
     FacesContext.getCurrentInstance().getViewRoot().setLocale(new Locale("zh","CN"));

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值