JSF 入门教程

来源:互联网 发布:淘宝米折报名入口 编辑:程序博客网 时间:2024/06/11 05:50

JSF(JavaServer Faces)介绍

JSF是JAVA EE规范的一部分。它是:Java Web应用的用户界面框架。

 

l        JSF提供一套API以及标签库,用来创建页面表单以及复杂的界面元素

l        JSF使得编写表单提交的代码更加简单,这些代码可以响应那些不同的按钮提交,改变某些值或某些用户的选择等等

l        Managed beans:使得JSF简化了处理请求参数的方法

l        EL(Expression Language):JSF有一套表达式语言用来访问java bean的属性以及集合元素等。

l        提供表单域类型转换以及验证

 

 

实现包

Apache的myfaces包是第一个开源的JSF实现。Myfaces有一些扩展的包,这些包是对JSF标准组件的扩充,可以协助我们更加快速的开发。Myfaces的扩展包括:

* Tomahawk :myfaces提供了一系列远远超过规范规定的组件,这些组件可以兼容JSF1.1的参考实现,以及其它兼容JSF1.1规范的其它实现,当然也兼容myfaces的JSF实现。

 

* Tobago:目标是提供一套基于JSF以及myfaces的良好设计的UI组件。Tobago不仅仅只是一套标签库。下面的几点让它与其它框架不同:

       -无需HTML设计,聚焦于商业应用程序的开发。开发者可以将精力集中在用户界面上,而不是网页。

       -UI组件是对HTML的抽象,它不仅仅可以用于HTML页面,它的输出格式可以定制。

       -“主题”机制,使得可以很容易切换应用程序的外观。

       -布局管理器可以自动排列组件,这就意味着无需使用HTML表格或其它技术来手工管理组件的布局。

 

* Trinidad:JSF1.1的组件库

 

最新的myfaces包(版本是:1.1.1)是对JSF1.1规范的实现。

 

安装JSF

 

1、在Eclipse中添加JSF的支持:

 

 

不要选择InstallJSF Jars and packaged TLDSInstallJSF TLDs,因为我们要安装的版本跟Eclipse支持的版本不一样,我们用的是新的版本。在MyEclipse中添加支持的目的,是为了可以使用MyEclipse的页面导航设计器,避免我们手工编写页面导航的繁琐性。

 

点击完成即可。

 

myEclipse添加了JSF的配置文件和修改了web.xml文件!

 

为了跟新版本的myfaces配合,我们最好将web.xml中关于myfaces的配置全部按照下面的说明重新配置一遍:

 

我们的例子以myfaces的实现包以及Tomahawk的扩展包作为学习JSF的起点。

依赖包可以在tomahawk-examples-1.1.6-bin的myfaces-example-blank-1.1.6.war中找到。

 

 

 

2、添加依赖包:

 

将依赖包拷贝到WEB-INF/lib下面,如果已经有的包,可以选择覆盖或不覆盖,然后解决其中版本有冲突的包,将低版本的包去掉!

冲突的包主要包括:commons-collections,commons-fileupload,commons-lang,commons-logging

 

3、修改web.xml文件,添加如下内容:

l        指定配置文件的位置

  <context-param>

    <param-name>javax.faces.CONFIG_FILES</param-name>

    <param-value>/WEB-INF/faces-config.xml</param-value>

  </context-param>

l        Tomahawk的过滤器,用于解释那些扩展的功能

  <filter>

    <filter-name>extensionsFilter</filter-name>

    <filter-class>org.apache.myfaces.webapp.filter.ExtensionsFilter</filter-class>

  </filter>

  <filter-mapping>

    <filter-name>extensionsFilter</filter-name>

    <url-pattern>*.jsf</url-pattern>

  </filter-mapping>

  <filter-mapping>

    <filter-name>extensionsFilter</filter-name>

    <url-pattern>/faces/*</url-pattern>

  </filter-mapping>

l        Myfaces的Servlet

  <servlet>

    <servlet-name>Faces Servlet</servlet-name>

    <servlet-class>javax.faces.webapp.FacesServlet</servlet-class>

    <load-on-startup>1</load-on-startup>

  </servlet>

  <servlet-mapping>

    <servlet-name>Faces Servlet</servlet-name>

    <url-pattern>*.jsf</url-pattern>

  </servlet-mapping>

 

 

4、在WEB-INF目录下,添加faces-config.xml配置文件

 

<?xmlversion="1.0"?>

<!DOCTYPEfaces-config PUBLIC

  "-//Sun Microsystems, Inc.//DTD JavaServer Faces Config 1.0//EN"

  "http://java.sun.com/dtd/web-facesconfig_1_1.dtd">

<faces-config>

   

</faces-config>

 

下面的例子,将结合MyEclipse对JSF的支持来开发JSF的程序。

 

实例1

 

1、 创建一个JSP

2、 在相同的路径下,用.jsf作为扩展名来访问.jsp文件。

 

Jsf使用同名的JSP来作为程序的展现,所以,可以通过JSF扩展名结尾的URL地址访问JSP页面。(为此,可能需要编写一个过滤器,将所有对JSP的访问全部重定向到同名的jsf扩展名结尾的URL地址)

 

实例2

我们创建一个表单,并提供一个按钮,点击按钮之后转向另外一个页面,这就涉及到了JSF页面编写的基本规则,以及页面导航。

 

l        首先创建一个JSP文件(jsf_01.jsp),并在JSP页面添加JSF的TAG LIB

<%@ tagliburi="http://java.sun.com/jsf/html"prefix="h" %>

<%@ taglib uri="http://java.sun.com/jsf/core"prefix="f" %>

 

l        添加view和form标签以及命令按钮

JSF的页面是由JSF的组件树组成的。这叫view。 view标签是视图的根,其它所有的JSF标签,必须被一个view标签包含!

 

 

form标签是页面表单。其它一些组件,比如文本输入框必须被包含在一个form标签的内部。

如:

<f:view>

    <h:form>

       <h:commandButtonaction="success"/>

    </h:form>

</f:view>

 

action 的值,是命令的结果,即点击之后,导向success!

 

l        创建另外一个JSP文件(jsf_01_success.jsp)

<%@ pagelanguage="java"contentType="text/html; charset=GB18030"

    pageEncoding="GB18030"%>

<!DOCTYPEHTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">

<html>

<head>

<metahttp-equiv="Content-Type"content="text/html; charset=GB18030">

<title>Insert title here</title>

</head>

<body>

转向成功

</body>

</html>

 

l        现在,我们需要在第一个页面和第二个页面之间建立关联,因为第一个页面有一个命令,它的结果是success。我们需要在faces-config.xml中配置导航规则。

<faces-config>

    <navigation-rule>

       <from-view-id>/jsf/test/jsf_01.jsp</from-view-id>

       <navigation-case>

           <from-outcome>success</from-outcome>

           <to-view-id>/jsf/test/jsf_01_success.jsp</to-view-id>

       </navigation-case>

    </navigation-rule>

</faces-config>

 

 

运行jsf_01.jsp之后,将出现一个命令按钮,点击之后,将转向jsf_01_success.jsp。

 

实例3

实例2中,只有一个命令按钮,我们在实例3中将多添加一个命令按钮,并增加一个转向:

Jsf_01.jsp改为:

<f:view>

    <h:form>

       <h:commandButtonaction="success"value="转向成功页面"/>

       <h:commandButtonaction="error"value="转向失败页面"/>

    </h:form>

</f:view>

Value 是显示的按钮的值。

 

添加jsf_01_error.jsp:

<%@ pagelanguage="java"contentType="text/html; charset=GB18030"

    pageEncoding="GB18030"%>

<!DOCTYPEHTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">

<html>

<head>

<metahttp-equiv="Content-Type"content="text/html; charset=GB18030">

<title>Insert title here</title>

</head>

<body>

转向错误

</body>

</html>

 

修改faces-confi.xml文件:

<faces-config>

    <navigation-rule>

       <from-view-id>/jsf/test/jsf_01.jsp</from-view-id>

       <navigation-case>

           <from-outcome>success</from-outcome>

           <to-view-id>/jsf/test/jsf_01_success.jsp</to-view-id>

       </navigation-case>

       <navigation-case>

           <from-outcome>error</from-outcome>

           <to-view-id>/jsf/test/jsf_01_error.jsp</to-view-id>

       </navigation-case>

    </navigation-rule>

</faces-config>

 

重新运行测试!

 

实例4

在实例2、3中,都是静态转向,也就是说,在命令按钮中规定了转向(成功或失败)。现在,我们需要动态的转向。也就是说,点击按钮之后,需要执行一个命令,根据命令的执行结果,决定转向!

 

这时候,我们需要一个支持的JavaBean(Backing Bean):

 

我们编写一个 非常简单的BackingBean01.java

package com.bjsxt.crm.web.jsf.test;

 

public class BackingBean01 {

       public String gogogo(){

              if(Math.random() > 0.5 ){

                     return "success";

              }

              return "error";

       }

}

 

 

然后,我们需要在faces-config.xml文件中注册这个Bean:

 

    <managed-bean>

       <managed-bean-name>firstbean</managed-bean-name>

        <managed-bean-class>com.bjsxt.crm.web.jsf.test.BackingBean01</managed-bean-class>

       <managed-bean-scope>request</managed-bean-scope>

    </managed-bean>

 

修改jsf_01.jsp文件为:

<f:view>

    <h:form>

       <h:commandButtonaction="success"value="转向成功页面"/>

       <h:commandButtonaction="error"value="转向失败页面"/>

       <h:commandButtonaction="#{firstbean.gogogo}" value="动态转向测试"/>

    </h:form>

</f:view>

在这里,action是一个动态表达式。这是JSF的表达式。Firstbean是bean的名字,后面是命令方法,这个方法返回值为String,它将决定其转向!

 

实例5

现在,该是传递一些数据的时候了!我们开发一个计算器,从页面上输入两个int值,计算结果将显示在另外一个页面上。

 

考虑JavaBean模型:

1、 BackingBean现在必须能够接收这两个int类型的值,并且需要能够输出结果,在JSF中,通过在BackingBean上定义属性做到这一点。

2、 BackingBean还应该负责计算这两个输入的值,这是一个命令方法。

 

我们添加number1、number2、result三个属性以及一个命令方法:

package com.bjsxt.crm.web.jsf.test;

 

public class BackingBean01 {

      

       private int number1;

       private int number2;

       private int result;

      

       public int getNumber1() {

              return number1;

       }

 

       public void setNumber1(int number1) {

              this.number1 = number1;

       }

 

       public int getNumber2() {

              return number2;

       }

 

       public void setNumber2(int number2) {

              this.number2 = number2;

       }

 

       public int getResult() {

              return result;

       }

 

       public void setResult(int result) {

              this.result = result;

       }

      

       public String compute(){

             

              result = number1 + number2;

             

              return "result";

       }

 

       public String gogogo(){

              if(Math.random() > 0.5 ){

                     return "success";

              }

              return "error";

       }

}

 

 

jsf_01.jsp 现在变为:

<%@ pagelanguage="java"contentType="text/html; charset=GB18030"

    pageEncoding="GB18030"%>

<%@ tagliburi="http://java.sun.com/jsf/html"prefix="h" %>

<%@ tagliburi="http://java.sun.com/jsf/core"prefix="f" %>

 

<!DOCTYPEHTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">

<html>

<head>

<metahttp-equiv="Content-Type"content="text/html; charset=GB18030">

<title>Insert title here</title>

</head>

<body>

<f:view>

    <h:form>

       <h:inputText value="#{firstbean.number1}"/>

       +

       <h:inputText value="#{firstbean.number2}"/>

       <h:commandButton action="#{firstbean.compute}" value="="/>

       <p>

       <h:commandButtonaction="success"value="转向成功页面"/>

       <h:commandButtonaction="error"value="转向失败页面"/>

       <h:commandButtonaction="#{firstbean.gogogo}" value="动态转向测试"/>

      

    </h:form>

</f:view>

</body>

</html>

 

Faces-config.xml变为:

<?xmlversion="1.0"encoding="UTF-8"?>

<!DOCTYPEfaces-config PUBLIC"-//Sun Microsystems, Inc.//DTD JavaServer Faces Config 1.1//EN""http://java.sun.com/dtd/web-facesconfig_1_1.dtd">

 

<faces-config>

 

    <managed-bean>

       <managed-bean-name>firstbean</managed-bean-name>

        <managed-bean-class>com.bjsxt.crm.web.jsf.test.BackingBean01</managed-bean-class>

       <managed-bean-scope>request</managed-bean-scope>

    </managed-bean>

    <navigation-rule>

       <from-view-id>/jsf/test/jsf_01.jsp</from-view-id>

       <navigation-case>

           <from-outcome>success</from-outcome>

           <to-view-id>/jsf/test/jsf_01_success.jsp</to-view-id>

       </navigation-case>

       <navigation-case>

           <from-outcome>error</from-outcome>

           <to-view-id>/jsf/test/jsf_01_error.jsp</to-view-id>

       </navigation-case>

       <navigation-case>

           <from-outcome>result</from-outcome>

           <to-view-id>/jsf/test/jsf_01_result.jsp</to-view-id>

       </navigation-case>

    </navigation-rule>

</faces-config>

 

 

 

 

添加jsf_01_result.jsp文件:

<%@ pagelanguage="java"contentType="text/html; charset=GB18030"

    pageEncoding="GB18030"%>

<%@ tagliburi="http://java.sun.com/jsf/html"prefix="h" %>

<%@ tagliburi="http://java.sun.com/jsf/core"prefix="f" %>

<!DOCTYPEHTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">

<html>

<head>

<metahttp-equiv="Content-Type"content="text/html; charset=GB18030">

<title>Insert title here</title>

</head>

<body>

<f:view>

<h:outputTextvalue="#{firstbean.number1}"/>

+

<h:outputTextvalue="#{firstbean.number2}"/>

=

<h:outputTextvalue="#{firstbean.result}"/>

</f:view>

</body>

</html>

在这个页面上,多了outputText标签,这个标签可以用来输出变量的值。

 

 

运行jsf_01.jsp,重新测试

 

现在我们已经了解了JSF如何在页面之间导航,如何跟后台的Java Bean一起配合完成一些任务。当然,只是一个简单的了解!但已经具备进一步深入学习的基础。

 

UI组件模型

JSF提供一套丰富灵活的组件模型,包括:

l        一套UIComponent类,定义UI组件的状态和行为。

l        呈现模型:定义如何用不同的方式来呈现组件

l        事件和监听器模型用来处理组件的事件。

l        转换模型:进行数据转换

l        验证模型:如何验证数据的合法性

 

UI组件类

比如UIForm、UIInput等等,具体请参考文档。

 

组件呈现模型

不同的组件会有不同的呈现方式,同一个组件可能会有不同的呈现方式,比如UISelectOne,可以使用radio来呈现,也可以使用下拉框来呈现等。这些,都是通过呈现模型来定义的。

 

数据转换模型

当一个组件绑定到一个对象上之后,对于组件数据来说,总共有两个视图:

一个是模型视图:从这个角度去看,数据表现为java对象的类型,如int,long,Date等等

一个是呈现视图:从这个角度去看,数据表现为一种可以被人读取或修改的形式。比如一个Date类型,可能被展现为一个yyyy-MM-dd格式的字符串,或者是三个字符串,分别代表年、月、日。

 

可以定义自己的转换器来转换数据。

 

事件与监听器模型

事件:值改变事件、动作事件、数据模型事件。

值改变:比如输入框的值被更改、选中了checkbox等

动作事件:点击按钮或超链接

数据模型事件:UIData组件的一行被选中的时候触发这个事件。

 

导航模型

Navigation-rule,可以包含一个from-view-id和多个navigation-case

每个navigation-case中,主要包括转向的页面。

From-view-id :当前页面

From-action:从哪个action方法

From-outcome:从哪个逻辑名称

To-view-id:转向哪个页面

 

导航解决的问题是:从哪里到哪里。一句话来说就是:从from-view-id页面,当from-action方法被调用而且其返回值是from-outcome的时候,转向to-view-id页面。

 

当导航发生的时候,即使没有调用action方法,但也会设置相应BackingBean的属性(如果当前的Form域绑定了属性的话)。

 

与spring整合

 

1、在faces-config.xml中定义:

    <application>

       <variable-resolver>

           org.springframework.web.jsf.DelegatingVariableResolver

       </variable-resolver>

    </application>

 

2、在Backing Bean中定义如下例所示:

package com.bjsxt.crm.web.jsf;

 

import com.bjsxt.crm.manager.UserManager;

import com.bjsxt.crm.model.User;

 

public class UserAction {

    private Useruser;

    private UserManager userManager;

   

    public User getUser() {

       if(user ==null){

           user = new User();

       }

       returnuser;

    }

 

    public void setUser(User user) {

       this.user = user;

    }

   

    public String add(){

      

       if(user ==null){

           System.out.println("用户数据是空的");

       }else{

           System.out.println(user.getUsername());

           System.out.println(user.getPassword());

       }

      

       userManager.addUser(user);

      

       return"add_success";

    }

 

    public void setUserManager(UserManager userManager) {

       this.userManager = userManager;

    }

   

}

 

 

3、在对应的JSF Backing Bean配置中,如下定义这个属性的值:

 

    <managed-bean>

       <managed-bean-name>userAction</managed-bean-name>

       <managed-bean-class>

           com.bjsxt.crm.web.jsf.UserAction

       </managed-bean-class>

       <managed-bean-scope>request</managed-bean-scope>

       <managed-property>

           <property-name>userManager</property-name>

           <value>#{userManager}</value>

       </managed-property>

    </managed-bean>

 

这样,在BackingBean中就可以自由调用spring中的对象了。

 

普通CRUD操作举例

 

 

 

 

0 0
原创粉丝点击