Java学习者论坛

 找回密码
 立即注册

QQ登录

只需一步,快速开始

手机号码,快捷登录

恭喜Java学习者论坛(https://www.javaxxz.com)已经为数万Java学习者服务超过8年了!积累会员资料超过10000G+
成为本站VIP会员,下载本站10000G+会员资源,购买链接:点击进入购买VIP会员
JAVA高级面试进阶视频教程Java架构师系统进阶VIP课程

分布式高可用全栈开发微服务教程

Go语言视频零基础入门到精通

Java架构师3期(课件+源码)

Java开发全终端实战租房项目视频教程

SpringBoot2.X入门到高级使用教程

大数据培训第六期全套视频教程

深度学习(CNN RNN GAN)算法原理

Java亿级流量电商系统视频教程

互联网架构师视频教程

年薪50万Spark2.0从入门到精通

年薪50万!人工智能学习路线教程

年薪50万!大数据从入门到精通学习路线年薪50万!机器学习入门到精通视频教程
仿小米商城类app和小程序视频教程深度学习数据分析基础到实战最新黑马javaEE2.1就业课程从 0到JVM实战高手教程 MySQL入门到精通教程
查看: 363|回复: 0

[jsf学习]JSF实现的自选语言界面

[复制链接]
  • TA的每日心情
    开心
    2021-3-12 23:18
  • 签到天数: 2 天

    [LV.1]初来乍到

    发表于 2014-10-9 23:48:55 | 显示全部楼层 |阅读模式
    问题描述:实现一个带自选语言栏的用户登录验证示例的国际化。对于这个实例分两部分来实现:先实现用户登录验证的国际化,再加上自选语言栏。


       
       
          
       
       
      
       第一部分:实现用户登录验证
       
      
       创建一个名为
       I18N_demo
       的
       JSF Web
       项目。
       
      
       1.         创建后台Bean
       
      
       在项目中创建一个后台
       Bean
       :
       RegistrationBean.java
       
      
       package org.qiujy.web.controller;
       
      
       
       
      
       import java.text.MessageFormat;
       
      
       import java.util.Locale;
       
      
       import java.util.ResourceBundle;
       
      
       
       
      
       public class RegistrationBean {
       
      
           private String userName;
       
      
           private String password;
       
      
       
       
      
           //
       以下是属性的
       getter
       和
       setter
       方法
       
      
           ......
       
      
       
       
      
           public String validate() {
       
      
                    boolean flag = true;
       
      
                    if (!"test".equals(userName)) {
       
      
                              FacesMessage msg = MessageFactory.getMessage(FacesContext
       
      
                                                .getCurrentInstance(), "field_ISERROR",
       
      
                                                new Object[] { "userName" });
       
      
                              FacesContext.getCurrentInstance().addMessage(null, msg);
       
      
                              flag = false;
       
      
                    }
       
      
                    if (!"123456".equals(password)) {
       
      
                              FacesMessage msg = MessageFactory.getMessage(FacesContext
       
      
                                                .getCurrentInstance(), "field_ISERROR",
       
      
                                                new Object[] { "password" });
       
      
                              FacesContext.getCurrentInstance().addMessage(null, msg);
       
      
                              flag = false;
       
      
                    }
       
      
       
       
      
                    if (flag) {
       
      
                              return "success";
       
      
                    } else {
       
      
                              return "failure";
       
      
                    }
       
      
           }
       
      
       }
       
      
       这个
       Bean
       中提供跟页面绑定的属性,以及跟动作按钮绑定的动作处理方法
       validate()
       ,在这个方法中需要注意的是,对用户名、密码都进行了相应的判断,如果是
       test
       、
       123456
       ,就是合法用户,返回结果字符串“
       success
       ”,否则是非法用户,通过
       JSF
       提供的
       MessageFactory
       来获取并创建好一则本地化错误消息(消息“键”是“
       field_ISERROR
       ”),添加到
       FacesContext
       中,然后返回结果字符串“
       failure
       ”。这样到了失败页面就可以取出相应的经过本地化的错误消息。
       
      
       2.         配置托管Bean和资源文件绑定
       
      
       在
       faces-config.xml
       文件中把
       RegistrationBean
       配置成托管
       Bean
       。同时为了支持国际化,指定了错误消息文件和资源文件,它们是同一个文件,就是存放在应用的
       org/qiujy/web/resources
       目录下的
       ApplicationMessages.properties
       文件,稍后再来看这个文件的内容:
       
      
       <faces-config>
       
      
       <application>
       
      
               <message-bundle>
       
      
       org.qiujy.web.resources.ApplicationMessages
       
      
       </message-bundle>
       
      
               <locale-config>
       
      
                        <default-locale>zh_CN</default-locale>
       
      
                        <supported-locale>en</supported-locale>
       
      
                        <supported-locale>zh_TW</supported-locale>
       
      
               </locale-config>
       
      
               
       
      
               <resource-bundle>
       
      
                        <base-name>
       
      
       org.qiujy.web.resources.ApplicationMessages
       
      
       </base-name>
       
      
                        <var>bundle</var>
       
      
               </resource-bundle>
       
      
       </application>
       
      
                
       
      
                <managed-bean>
       
      
                          <managed-bean-name>registrationBean</managed-bean-name>
       
      
                          <managed-bean-class>
       
      
                                   org.qiujy.web.controller.RegistrationBean
       
      
                          </managed-bean-class>
       
      
                          <managed-bean-scope>request</managed-bean-scope>
       
      
                </managed-bean>
       
      
                ......
       
      
       </faces-config>
       
      
       3.         创建页面和本地化资源文件
       
      
       用户登录页面:
       userlogin.jsp
       
      
       <%@ page language="java" pageEncoding="UTF-8"%>
       
      
       <%@ taglib uri="http://java.sun.com/jsf/HTML" prefix="h"%>
       
      
       <%@ taglib uri="http://java.sun.com/jsf/core" prefix="f"%>
       
      
       
       
      
       <f:view>
       
      
                <html>
       
      
                          <head>
       
      
                                   <title><h:outputText value="#{bundle.title_login}" /></title>
       
      
                          </head>
       
      
       
       
      
                          <body>
       
      
                                   <h:form id="loginForm">
       
      
                                            <h:panelGrid columns="2">
       
      
                                                      <h:graphicImage url="#{bundle.login_logo}"
       
      
                                                                                           width="220" height="160"/>
       
      
                                           
       
      
                                                      <h:panelGrid columns="3">
       
      
                                                               <f:facet name="caption">
       
      
                                                                        <h:outputText value="#{bundle.title_login}" />
       
      
                                                               </f:facet>
       
      
                
       
      
                                                               <h:outputText value="#{bundle.login_userName}" />
       
      
                                                               <h:inputText id="textName"
       
      
                                                                        value="#{registrationBean.userName}"
       
      
                                                                        required="true">
       
      
                                                                                  
       
      
                                                               </h:inputText>
       
      
                                                               <h:message for="textName" style="color:red" />
       
      
                
       
      
                                                               <h:outputText value="#{bundle.login_password}" />
       
      
                                                               <h:inputSecret id="textPwd"
       
      
                                                                        value="#{registrationBean.password}"
       
      
                                                                        required="true">
       
      
                                                                        <f:validateLength minimum="6" maximum="20"/>
       
      
                                                               </h:inputSecret>
       
      
                                                               <h:message for="textPwd" style="color:red" />
       
      
                
       
      
                                                               <f:facet name="footer">
       
      
                                                                        <h:panelGroup>
       
      
                                                                                  <h:commandButton value="#{bundle.button_submit}"
       
      
                                                                                           action="#{registrationBean.validate}" />
       
      
                                                                                  <h:outputText value=" "></h:outputText>
       
      
                                                                                  <h:commandButton value="#{bundle.button_reset}"
       
      
                                                                                           type="reset" />
       
      
                                                                        </h:panelGroup>
       
      
                                                               </f:facet>
       
      
                                                      </h:panelGrid>
       
      
                                            </h:panelGrid>
       
      
                                   </h:form>
       
      
                          </body>
       
      
                </html>
       
      
       </f:view>
       
      
       在这个页面中,所有静态文本,错误消息都通过值表达式用资源文件的别名“
       bundle
       ”来获取的。所有的资源消息“键”在本地化资源文件中都配置了相应的“值”,如下:
       
      
       代码片段
       7.15
        缺省的资源文件
       ApplicationMessages.properties
       
      
       button_submit=Submit
       
      
       button_reset=Reset
       
      
       button_back=Back
       
      
       
       
      
       title_login=User Login Page
       
      
       login_userName=UserName:
       
      
       login_password=Password:
       
      
       login_logo=/images/jsf_i18n_en.gif
       
      
       
       
      
       success_welcome=Welcome:
       
      
       failure_error=Failure!
       
      
       field_ISERROR= {0} is error.
       
      
                
       英文的资源文件
       ApplicationMessages_en.properties
       的内容跟这个相同。下面再来看简体中文的资源文件:
       
      
       简体中文的资源文件
       ApplicationMessages_zh_CN.properties
       
      
       button_submit=
       提交
       
      
       button_reset=
       重置
       
      
       button_back=
       后退
       
      
       
       
      
       title_login=
       用户登录页面
       
      
       login_userName=
       用户名
       :
       
      
       login_password=
       密码
       ::
       
      
       login_logo=/images/jsf_i18n_zh_CN.gif
       
      
       
       
      
       success_welcome=
       欢迎
       :
       
      
       failure_error=
       失败
       !
       
      
       field_ISERROR= {0}
       不正确
       
      
                
       需要注意是,使用是别忘了进行
       Uncodei
       编码转换。至于繁体中文的资源文件也跟这个文件差不多,在此不再赘述。
       
      
                
       另外要对标准的错误消息进行国际化,可以把
       SUN
       的
       RI
       实现中的错误消息全部复制到本地化资源文件中,对简体中文的资源进行汉化,由于内容较多,在这就不帖出代码了,具体可能看本例的源代码。
       
      
       接下来看登录成功后的页面的代码:
       success.jsp
       
      
                      
       
      
       <%@ page language="java" pageEncoding="UTF-8"%>
       
      
       <%@ taglib uri="http://java.sun.com/jsf/html" prefix="h"%>
       
      
       <%@ taglib uri="http://java.sun.com/jsf/core" prefix="f"%>
       
      
       <f:view>
       
      
                <html>
       
      
                          <head>
       
      
                                   <title><h:outputText value="#{bundle.success_welcome}"/></title>
       
      
                          </head>
       
      
                          <body>
       
      
                                   <h2>
       
      
                                            <h:outputText value="#{bundle.success_welcome}" />
       
      
                                            <h:outputText value="#{registrationBean.userName}" />
       
      
                                   </h2>
       
      
                          <jsp:useBean id="currentDate" class="java.util.Date" scope="request"/>
       
      
                                   <h:outputText value="#{currentDate}">
       
      
                                            <f:convertDateTime type="both"/>
       
      
                                   </h:outputText>
       
      
                          </body>
       
      
                </html>
       
      
       </f:view>
       
      
       在这个页面中,为了演示日期时间的国际化,先创建了一个日期对象,然后用
       Output
       组件标签输出,并给这个标签注册了
       DateTimeConverter
       ,这样就能实现日期时间的国际化了。
       
      
       最后再来看登录失败页面的代码:
       failure.jsp
       
      
       <%@ page language="java" pageEncoding="UTF-8"%>
       
      
       <%@ taglib uri="http://java.sun.com/jsf/html" prefix="h" %>
       
      
       <%@ taglib uri="http://java.sun.com/jsf/core" prefix="f" %>
       
      
       <f:view>
       
      
                <html>
       
      
                          <head>
       
      
                                   <title><h:outputText value="#{bundle.failure_error}"/></title>
       
      
                          </head>
       
      
                          <body>
       
      
                                   <h2><h:outputText value="#{bundle.failure_error}"/></h2>
       
      
                                   <h:messages style="color:red"/><br/>
       
      
                                   <h:outputLink value="userlogin.faces">
       
      
                                            <h:outputText value="#{bundle.button_back}"/>
       
      
                                   </h:outputLink>
       
      
                          </body>
       
      
                </html>
       
      
       </f:view>
       
      
       在这个页面,用
       <h:message>
       标签输出了登录失败的原因,这个错误消息是在后台
       Bean
       中的
       validate()
       方法中从资源文件中引用的经过本地化后的消息。
       
      
       4.         配置导航规则
       
      
       导航规则比较简单,直接看代码:
       
      
       <navigation-rule>
       
      
                <from-view-id>/userlogin.jsp</from-view-id>
       
      
                <navigation-case>
       
      
                          <from-outcome>success</from-outcome>
       
      
                          <to-view-id>/success.jsp</to-view-id>
       
      
                </navigation-case>
       
      
                <navigation-case>
       
      
                          <from-outcome>failure</from-outcome>
       
      
                          <to-view-id>/failure.jsp</to-view-id>
       
      
                </navigation-case>
       
      
       </navigation-rule>
       
      
       第二部分:
        实现自选语言栏
       
      
       实现页面的语言可以让用户根据自己的喜好进行选择,也是在做
       web
       应用时比较常见的一个功能。下面就来完成这个任务。
       
      
       1.         创建后台Bean
       
      
       在这个应用中添加一个处理用户自选语言的后台
       Bean
       ,
       LanguageSelectorBean
       ,代码如下:
       
      
       package org.qiujy.common;
       
      
       
       
      
       import java.util.HashMap;
       
      
       import java.util.Locale;
       
      
       import java.util.Map;
       
      
       
       
      
       import javax.faces.context.FacesContext;
       
      
       import javax.faces.event.ValueChangeEvent;
       
      
       
       
      
       public class LanguageSelectorBean {
       
      
                private String currentLocale;
       
      
       
       
      
                //
       本应用支持的语言
       Map
       
      
                private Map<String, Locale> supportLocals;
       
      
       
       
      
                public LanguageSelectorBean() {
       
      
                          supportLocals = new HashMap<String, Locale>();
       
      
                          supportLocals.put("zh_CN", Locale.CHINA);
       
      
                          supportLocals.put("zh_TW", Locale.TAIWAN);
       
      
                          supportLocals.put("en", Locale.ENGLISH);
       
      
       
       
      
                          this.currentLocale = FacesContext.getCurrentInstance().getViewRoot()
       
      
                                            .getLocale().toString();
       
      
                }
       
      
       
       
      
                public String getCurrentLocale() {
       
      
                          return currentLocale;
       
      
                }
       
      
       
       
      
                public void setCurrentLocale(String currentLocale) {
       
      
                          this.currentLocale = currentLocale;
       
      
                }
       
      
       
       
      
                //
       改变当前语言区域的事件处理方法
       
      
                public void changeLocale(ValueChangeEvent event) {
       
      
                          String currentLocale = (String) event.getNewValue();
       
      
                          //
       设置当前的语言区域
       
      
                          Locale myLocale = this.supportLocals.get(currentLocale);
       
      
                          FacesContext.getCurrentInstance().getViewRoot().setLocale(myLocale);
       
      
       
       
      
                          //
       把自定义语言存放到
       Session
       
       
      
                          HttpServletRequest request = (HttpServletRequest) FacesContext
       
      
                                            .getCurrentInstance().getExternalContext().getRequest();
       
      
                          request.getSession().setAttribute("myLocale", myLocale);
       
      
                }
       
      
       }
       
      
                
       在这个后台
       Bean
       中有一个值改变事件处理方法
       changeLocale()
       ,它根据用户选中的语言代码来更改当前
       FacesContext
       中的视图的默认语言区域。同时,为了让当前用户的整个会话过程的语言区域都是用户的自行选择的,需要把用户选择的语言区域对象存放到
       Session
       中。
       
      
       2.         创建阶段事件监听器来设置自选语言环境
       
      
       用户设置好语言环境后,要想在当前会话的后续请求中继续生效,就要在所有
       JSF
       请求处理生命周期的“呈现响应阶段”发生前更改当前
       FacesContext
       中的视图的默认语言区域,这个任务交由阶段事件监听器来实现。所在,在本应用中还要添加一个阶段事件监听器的实现类。如:
       
      
       package org.qiujy.common;
       
      
       
       
      
       import java.util.Locale;
       
      
       
       
      
       import javax.faces.context.FacesContext;
       
      
       import javax.faces.event.PhaseEvent;
       
      
       import javax.faces.event.PhaseId;
       
      
       import javax.faces.event.PhaseListener;
       
      
       import javax.servlet.http.HttpServletRequest;
       
      
       
       
      
       /**
       
      
        *
       阶段事件监听器实现类:主要是用来设置自选语言环境
       
      
       */
       
      
       @SuppressWarnings("serial")
       
      
       public class MyPhaseListener implements PhaseListener {
       
      
                /**
       
      
                 *
       结束某个阶段时会调用到的方法
       
      
                 */
       
      
                public void afterPhase(PhaseEvent pe) {
       
      
                }
       
      
       
       
      
                /**
       
      
                 *
       开始某个阶段时会调用到的方法
       
      
                 */
       
      
                public void beforePhase(PhaseEvent pe) {
       
      
                          System.out.println("this is Phase: " + pe.getPhaseId().toString());
       
      
                          //
       呈现响应阶段
       ,
       设置自选语言环境
       
      
                          HttpServletRequest request = (HttpServletRequest) FacesContext
       
      
                                            .getCurrentInstance().getExternalContext().getRequest();
       
      
       
       
      
                          Locale myLocale = (Locale) request.getSession().getAttribute("myLocale");
       
      
                          System.out.println("current request locale is: "
       
      
                                            + FacesContext.getCurrentInstance().getViewRoot().getLocale()
       
      
                                                               .toString());
       
      
       
       
      
                          if (myLocale != null) {
       
      
                                   FacesContext.getCurrentInstance().getViewRoot().setLocale(myLocale);
       
      
       
       
      
                                   System.out.println("current Custom locale is: "
       
      
                                                      + FacesContext.getCurrentInstance().getViewRoot()
       
      
                                                                        .getLocale().toString());
       
      
                          }
       
      
                }
       
      
       
       
      
                /**
       
      
                 *
       只监听
       "
       呈现响应阶段
       "
       
      
                 */
       
      
                public PhaseId getPhaseId() {
       
      
                          return PhaseId.RENDER_RESPONSE;
       
      
                }
       
      
       }
       
      
       这个类实现了
       PhaseListener
       接口,通过在
       getPhashId()
       方法中返回
       PhaseId.RENDER_RESPONSE
       来监听“呈现响应阶段”事件,在开始“呈现响应阶段”事件时,会调用本类的
       beforePhase()
       方法,在这个方法中,通过从
       Session
       对象中取出用户设置好的语言环境,来更改当前
       FacesContext
       中的视图的默认语言区域。这样,当前会话的后续响应都会用用户选择的语言环境来呈现视图了。注意,要把此监听器类配置在
       faces-config.xml
       中,它的作用才生效,如:
       
      
       <lifecycle>
       
      
                <phase-listener>
       
      
                          org.qiujy.common.MyPhaseListener
       
      
                </phase-listener>
       
      
       </lifecycle>
       
      
       3.         配置托管Bean和资源文件绑定
       
      
       像其它托管
       Bean
       一样,把它配置在
       faces-config.xml
       文件中,但要注意一点的是,这个托管
       Bean
       的存放范围应该选择
       session
       ,这样才能保证对语言区域的选择在当前用户的整个会话过程中都有效。
       
      
       <managed-bean>
       
      
                <managed-bean-name>languageSelectorBean</managed-bean-name>
       
      
                <managed-bean-class>
       
      
                          org.qiujy.common.LanguageSelectorBean
       
      
                </managed-bean-class>
       
      
                <managed-bean-scope>session</managed-bean-scope>
       
      
       </managed-bean>
       
      
       4.         创建页面和本地化资源文件
       
      
       接下来创建一个语言选择栏页面:
       
      
       <%@ page language="java" pageEncoding="UTF-8"%>
       
      
       <%@ taglib uri="http://java.sun.com/jsf/html" prefix="h"%>
       
      
       <%@ taglib uri="http://java.sun.com/jsf/core" prefix="f"%>
       
      
       
       
      
       <f:subview id="languageView">
       
      
                <h:form id="languageForm"
       
      
                          style="background-color:#bbbbbb; padding-top:4px; padding-bottom:4px;">
       
      
                          <h:outputText value="#{bundle.selectYourLocale}"></h:outputText>
       
      
                          <h:selectOneMenu value="#{languageSelectorBean.currentLocale}"
       
      
                                   immediate="true" onchange="submit();"
       
      
                                   valueChangeListener="#{languageSelectorBean.changeLocale}">
       
      
                                   <f:selectItem itemValue="zh_CN" itemLabel="#{bundle.zh_CNText}" />
       
      
                                   <f:selectItem itemValue="zh_TW" itemLabel="#{bundle.zh_TWText}" />
       
      
                                   <f:selectItem itemValue="en" itemLabel="#{bundle.enText}" />
       
      
                          </h:selectOneMenu>
       
      
                </h:form>
       
      
       </f:subview>
       
      
       这个页面的特殊之处有三处:
       
      
       q
       它的根视图标签是
       <f:subview>
       ,而不是常用的
       <f:view>
       了,这是因为这个页面经常是用来内嵌到其它页面的,而
       JSF
       规范又要求一个页面只能有一个
       <f:view>
       顶层视图,所以就只能用
       <f:subview>
       来创建一个子视图。
       
      
       q
       给
       selectOneMenu
       组件添加了一个值改变事件监听器,同时添加了一个
       JavaScript
       的
       onchange
       事件来提交表单,这样在改变下拉菜单的选中项时,会提交表单,同时会触发值改变事件。这样就能实现改变语言区域的功能了。
       
      
       q
       把
       selectOneMenu
       组件的
       immediate
       属性值设置为
       true
       ,这样可以使这个组件提交表单时,请求处理生命周期的应用请求阶段就会调用值改变事件的处理方法,从而把应用验证“短路”掉,这样即使页面的一些必填字段(本例中的用户名,密码)没有输入值,也不会报错了。
       
      
       最后,还要在所有的本地化资源文件中分别加上这个页面中出现的消息“键
       -
       值”对,例如在缺省的资源文件中添加如下代码:
       
      
       zh_CNText=Chinese,Simplify
       
      
       zh_TWText=Chinese,Traditional
       
      
       enText=English
       
      
       selectYourLocale=Select Language:
       
      
       5.         在页面上包含自选语言栏页面
       
      
       在用户登录页面中用
       JSP
       的
       include
       动作把自选语言栏页面包含进来,在
       userlogin.jsp
       页面
       body
       体的首行添加如下代码:
       
      
       <jsp:include page="languageSelector.jsp"/>
       
      
       6.         运行查看效果
       
      
       到此整个应用开发完毕,项目目录结构如图
       :
       
      
       
       
      
       自选语言项目目录结构图
       
      
       重新部署应用,运行,访问主页:
       
      
       
       
      
             
       
      
       中文主页图
       
      
       通过在下拉列表选中“英文”来更新想要的英文界面:
       
      
       
       

       

       

       
      
       英文主页图
       ?
      

      



      
      
       
       

         
       

         
       
      
    复制代码
    回复

    使用道具 举报

    您需要登录后才可以回帖 登录 | 立即注册

    本版积分规则

    QQ|手机版|Java学习者论坛 ( 声明:本站资料整理自互联网,用于Java学习者交流学习使用,对资料版权不负任何法律责任,若有侵权请及时联系客服屏蔽删除 )

    GMT+8, 2024-6-16 08:48 , Processed in 0.503563 second(s), 48 queries .

    Powered by Discuz! X3.4

    © 2001-2017 Comsenz Inc.

    快速回复 返回顶部 返回列表