欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

JSF框架整理(一)

程序员文章站 2022-03-14 10:29:01
...

一、框架简介

        JavaServer Faces (JSF) 是一种用于构建Java Web 应用程序的标准框架,它提供了一种以组件为中心的用户界面(UI)构建方法,从而简化了Java服务器端应用程序的开发。

典型的JSF应用程序包含下列部分:

  • 一组JSP页面

  • 一组后台bean(为在一个页面上的UI组件定义的属性和函数的JavaBean组件)

  • 应用程序配置资源文件(定义页面导航规则、配置bean和其它的自定对象,如自定义组件)

  • 部署描述文件(web.xml)

  • 一组由应用程序开发者创建的自定义对象(有可能)

  • 一些可能包含自定义组件、约束、转换器或者监听器的对象

  • 为在页面中表现自定义对象的一组自定义tag

包含JSP页面的JSF应用程序也使用由为了表现UI组件和在页面上的其他对象的JSF技术而定义的标准的tag库。

二、JSF生命周期

JSF(JavaServer Faces)应用程序框架的简单程序是自动管理生命周期阶段,并允许您手动管理。JSF(JavaServer Faces)应用程序的生命周期从客户端对页面发出HTTP请求时开始,并在服务器响应页面时结束。

JSF生命周期分为两个主要阶段:

  • 执行阶段
  • 渲染阶段

1. 执行阶段

在执行阶段,当第一次请求时,构建或恢复应用程序视图。 对于其他后续请求,执行其他操作,如应用请求参数值,对组件值执行转换和验证,受托管的bean将使用组件值进行更新,并调用应用程序逻辑。
执行阶段被进一步分成以下子阶段。

  • 恢复视图阶段
  • 应用请求值阶段
  • 流程验证阶段
  • 更新模型值阶段
  • 调用应用阶段
  • 渲染响应阶段

      a:恢复视图阶段

       当客户端请求一个JavaServer Faces页面时,JavaServer Faces实现开始恢复视图阶段。 在此阶段,JSF将视图中的组件构建为请求页面,线性事件处理程序和验证器的视图,并将视图保存在FacesContext实例中。

       如果对该页面的请求是回发,那么与该页面相对应的视图已经存在于FacesContext实例中。 在此阶段,JavaServer Faces实现通过使用保存在客户端或服务器上的状态信息来还原视图。

      b:应用请求值阶段

       在此阶段,在回发请求期间恢复组件树。 组件树是表单元素的集合。树中的每个组件通过使用其decode(processDecodes())方法从请求参数中提取其新值。 之后,该值将本地存储在每个组件上。

  • 如果任何解码方法或事件侦听器在当前FacesContext实例上调用了renderResponse方法,则JavaServer Faces实现将跳过“渲染响应”阶段。
  • 如果任何事件在此阶段已排队,则JavaServer Faces实现将事件广播到有兴趣的监听器。
  • 如果应用程序需要重定向到其他Web应用程序资源或生成不包含任何JavaServer Faces组件的响应,则可以调用FacesContext.responseComplete()方法。
  • 如果当前请求被识别为部分请求,则从FacesContext检索部分上下文,并应用部分处理方法。

     c:流程验证阶段

      在此阶段,JavaServer Faces通过使用其validate()方法来处理在组件上注册的所有验证器。 它检查指定验证规则的组件属性,并将这些规则与为组件存储的本地值进行比较。 JavaServer Faces还完成了没有将immediate属性设置为true的输入组件的转换。

  • 如果任何验证方法或事件侦听器在当前FacesContext上调用了renderResponse方法,则JavaServer Faces实现将跳过“渲染响应”阶段。
  • 如果应用程序需要重定向到不同的Web应用程序资源或生成不包含任何JavaServer Faces组件的响应,则可以调用FacesContext.responseComplete方法。
  • 如果事件在此阶段已排队,则JavaServer Faces实现将它们广播给有兴趣的监听器。
  • 如果当前请求被识别为部分请求,则从FacesContext检索部分上下文,并应用部分处理方法。

      d:更新模型值阶段

        确保数据有效后,它遍历组件树,并将相应的服务器端对象属性设置为组件的本地值。 JavaServer Faces实现只更新输入组件的value属性指向bean属性。 如果本地数据无法转换为bean属性指定的类型,生命周期将直接前进到“渲染响应”阶段,以便重新呈现页面并显示错误。

  • 如果任何updateModels方法或任何监听器在当前FacesContext实例上调用了renderResponse()方法,则JavaServer Faces实现将跳过“渲染响应”阶段。
  • 如果应用程序需要重定向到其他Web应用程序资源或生成不包含任何JavaServer Faces组件的响应,则可以调用FacesContext.responseComplete()方法。
  • 如果任何事件在此阶段已排队,JavaServer Faces实现将它们广播到有兴趣的监听器。
  • 如果当前请求被识别为部分请求,则从FacesContext检索部分上下文,并应用部分处理方法。

       e:调用应用阶段

         在此阶段,JSF处理应用程序级事件,例如提交表单或链接到另一个页面。
现在,如果应用程序需要重定向到其他Web应用程序资源或生成不包含任何JSF组件的响应,则可以调用FacesContext.responseComplete()方法。

之后,JavaServer Faces实现将控制转移到“渲染响应”阶段。

      f:渲染响应阶段

      这是JSF生命周期的最后阶段。 在此阶段,JSF将构建视图并将权限委托给相应的资源来呈现页面。

  • 如果这是初始请求,则页面上表示的组件将被添加到组件树中。
  • 如果这不是初始请求,组件已经添加到树中,不需要再添加。
  • 如果请求是回应,并且在应用请求值阶段,过程验证阶段或更新模型值阶段期间遇到错误,则在此阶段将再次呈现原始页面。

   如果页面包含h:messageh:messages标签,页面上会显示任何排队的错误消息。
在渲染视图的内容之后,保存响应的状态,以便后续请求可以访问它。 恢复视图阶段可以使用保存的状态。

 

2. 渲染阶段

在此阶段,请求的视图作为对客户端浏览器的响应。 视图渲染是以HTML或XHTML生成输出的过程。 所以,用户可以在浏览器看到它。

在渲染过程中采取以下步骤。

  • 当客户端对index.xhtml网页进行初始请求时,编译应用程序。
  • 应用程序在编译后执行,并为应用程序构建一个新的组件树,并放置在FacesContext中。
  • 使用由EL表达式表示的组件和与其关联受托管bean属性填充组件树。
  • 基于组件树。 建立了新的视图。
  • 该视图作为响应呈现给请求客户端。
  • 组件树被自动销毁。
  • 在后续请求中,重新构建组件树,并应用已保存的状态。

三、JSF托管Bean

      托管bean它是一个纯Java类,它包含一组属性和一组gettersetter方法。

  以下是托管bean方法执行的常见功能:

  • 验证组件的数据
  • 处理组件触发的事件
  • 执行处理以确定应用程序必须导航的下一页
  • 它也可以作为JFS框架的模型。

1、JSF托管Bean示例:

    请看看下面一段示例代码 :

public class User {  
    private String name;  
    public String getName() {  
        return name;  
    }  
    public void setName(String name) {  
        this.name = name;  
    }   
}

您可以通过以下方式使用此bean

  • 通过配置成XML文件。
  • 通过使用注释。

   a:通过XML文件配置托管Bean:

<managed-bean>  
    <managed-bean-name>user</managed-bean-name>  
    <managed-bean-class>User</managed-bean-class>  
    <managed-bean-scope>session</managed-bean-scope>  
</managed-bean>

在xml文件配置bean是比较旧方法。 在这种方法中,我们必须创建一个名为faces-config.xml的xml文件,JSF提供了配置bean的标签。

在上面的例子中,我们列出了bean-namebean-classbean-scope。 所以,它可以在项目中访问。

   b:使用注释配置托管Bean:

import javax.faces.bean.ManagedBean;  
import javax.faces.bean.RequestScoped;  

@ManagedBean    // Using ManagedBean annotation  
@RequestScoped  // Using Scope annotation  
public class User {  
    private String name;  
    public String getName() {  
        return name;  
    }  
    public void setName(String name) {  
         this.name = name;  
    }  
}

     类中的@ManagedBean注解自动将该类注册为JavaServer Faces的资源。 这种注册的托管bean在应用程序配置资源文件中不需要托管bean配置项。

  @ManagedBean将bean标识为名称属性中指定的名称的托管bean。如果未指定name属性,那么托管bean名称将默认为简单的类名称,其中第一个字母小写。 在我们的情况下是helloWorld
如果eager设置为“true”,则在请求之前创建托管bean。如果使用“lazy”初始化,只有在请求时才会创建bean。

  这是应用程序配置资源文件方法的替代方法,并减少配置托管bean的任务。
  @RequestScoped注释用于提供托管的范围。 您可以使用注解来定义bean将被存储的范围。

@ManagedBean(name = "helloWorld", eager = true)
@RequestScoped
public class HelloWorld {

   @ManagedProperty(value="#{message}")
   private Message message;
   ...
}

 您可以对bean类使用以下范围:

  • 应用程序(@ApplicationScoped):应用程序范围在所有用户中保持不变,与Web应用程序的交互。( bean只要Web应用程序生存。 它在第一个HTTP请求或Web应用程序启动时创建,并且在@ManagedBean中设置属性eager = true,并在Web应用程序关闭时被销毁)。
  • 会话(@SessionScoped):会话范围在Web应用程序中的多个HTTP请求中保持不变。(bean只要HTTP会话生存。 它在第一个HTTP请求时创建,并在HTTP会话无效时被销毁)。
  • 视图(@ViewScoped):在用户与Web应用程序的单个页面(视图)进行交互时,视图范围仍然存在。(bean只要用户在浏览器窗口中与同一JSF视图进行交互即可。 它根据HTTP请求创建,并在用户导航到其他视图时被销毁)。
  • 请求(@RequestScoped):在Web应用程序中的单个HTTP请求期间,请求范围仍然存在。(bean只要HTTP请求响应就行。它根据HTTP请求创建,并在与HTTP请求相关联的HTTP响应完成时被销毁)。
  • 无(@NoneScoped):表示未为应用程序定义作用域。(bean与单个表达式语言(EL)求值时间一样长。 在EL求值评估时创建,并在EL求值评估后被销毁)。
  • 自定义(@CustomScoped):用户定义的非标准作用域。 其值必须配置为java.util.Map,自定义范围很少使用。(bean只要在为此范围创建的自定义Map中的bean的条目生效)。

急切管理Bean

托管bean默认是懒惰的。 这意味着,只有在从应用程序发出请求时才会去实例化bean。
如果想自动提前强制将bean实例化,那么可在应用程序启动时,可以强制将bean实例化并放置在应用程序(@ApplicationScoped)范围内。您需要将托管 bean 的eager属性设置为true,如以下示例所示:

@ManagedBean(eager=true)

@ManagedProperty注释

JSF是一个简单的静态依赖注入(DI)框架。 @ManagedProperty注释标记被托管的bean的属性以注入另一个受托管的Bean。

2、如何进行bean注入

我们先定义一个消息bean,它有一个字符串属性来存储消息。

@ManagedBean(name="message")
@SessionScoped
public class MessageBean implements Serializable {

  private static final long serialVersionUID = 1L;

  private String sayWelcome = "Welcome to JSF 2.0";

然后我们再定义另一个托管bean,并使用@ManagedProperty注解注入MessageBean

@ManagedBean
@SessionScoped
public class UserBean implements Serializable {

  private static final long serialVersionUID = 1L;

  @ManagedProperty(value="#{message}")
  private MessageBean messageBean;

  public void setMessageBean(MessageBean messageBean) {
    this.messageBean = messageBean;
  }

实例:

     创建一个名为: InjectManagedBeans 的工程,并加入以下文件代码。
以下是文件:UserBean.java 中的代码 

package com.yiibai;

import java.io.Serializable;

import javax.faces.bean.ManagedBean;
import javax.faces.bean.ManagedProperty;
import javax.faces.bean.SessionScoped;

@ManagedBean
@SessionScoped
public class UserBean implements Serializable {

  private static final long serialVersionUID = 1L;

  @ManagedProperty(value="#{message}")
  private MessageBean messageBean;

  public void setMessageBean(MessageBean messageBean) {
    this.messageBean = messageBean;
  }

  private String name;

  public String getName() {
    return name;
  }

  public void setName(String name) {
    this.name = name;
  }

  public String getSayWelcome(){
    //check if null?
    if("".equals(name) || name ==null){
      return "";
    }else{
      return messageBean.getSayWelcome() + name;
    }
  }

}

以下是是文件:index.xhtml 中的代码 

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" 
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"
      xmlns:f="http://java.sun.com/jsf/core"      
      xmlns:h="http://java.sun.com/jsf/html">

    <h:body>

      <h:form>
         <h:inputText id="name" value="#{userBean.name}"></h:inputText>
         <h:commandButton value="Welcome Me">
         <f:ajax execute="name" render="output" />
         </h:commandButton>

         <h2><h:outputText id="output" value="#{userBean.sayWelcome}" /></h2>  
      </h:form>

    </h:body>
</html>

以下是文件:MessageBean.java 中的代码 

package com.yiibai;
import java.io.Serializable;

import javax.faces.bean.ManagedBean;
import javax.faces.bean.SessionScoped;

@ManagedBean(name="message")
@SessionScoped
public class MessageBean implements Serializable {

  private static final long serialVersionUID = 1L;

  private String sayWelcome = "Welcome to JSF 2.0";

  public String getSayWelcome() {
    return sayWelcome;
  }

  public void setSayWelcome(String sayWelcome) {
    this.sayWelcome = sayWelcome;
  }

}

运行测试结果:

Tomcat启动完成后,在浏览器地址栏中输入以下URL。

http://localhost:8084/InjectManagedBeans/

运行结果如下所示 
JSF框架整理(一)

相关标签: 框架