JSF 快速指南



JSF - 概述

什么是 JSF?

JavaServer Faces (JSF) 是一种 MVC Web 框架,它使用页面中可重用的 UI 组件简化了基于服务器的应用程序的用户界面 (UI) 的构建。JSF 提供了一种将 UI 小部件连接到数据源和服务器端事件处理程序的功能。JSF 规范定义了一组标准的 UI 组件,并为开发组件提供了应用程序编程接口 (API)。JSF 支持对现有标准 UI 组件的重用和扩展。

优点

JSF 减少了创建和维护应用程序的工作量,这些应用程序将在 Java 应用程序服务器上运行,并将应用程序 UI 呈现到目标客户端。JSF 通过以下方式促进 Web 应用程序开发:-

  • 提供可重用的 UI 组件
  • 简化 UI 组件之间的数据传输
  • 管理跨多个服务器请求的 UI 状态
  • 支持自定义组件的实现
  • 将客户端事件连接到服务器端应用程序代码

JSF UI 组件模型

JSF 使开发人员能够从 UI 组件集合中创建 Web 应用程序,这些组件可以针对多种客户端类型以不同的方式呈现自身(例如 - HTML 浏览器、无线或 WAP 设备)。

JSF 提供了 -

  • 核心库

  • 一组基本 UI 组件 - 标准 HTML 输入元素

  • 扩展基本 UI 组件以创建其他 UI 组件库或扩展现有组件

  • 多种渲染功能,使 JSF UI 组件能够根据客户端类型以不同的方式呈现自身

JSF - 环境搭建

本章将指导您如何准备开发环境以开始使用 JSF 框架。在设置 JSF 框架之前,您将学习如何在您的机器上设置 JDK、Eclipse、Maven 和 Tomcat。

系统要求

JSF 需要 JDK 1.5 或更高版本,因此第一个要求是在您的机器上安装 JDK。

JDK 1.5 或以上
内存 无最低要求
磁盘空间 无最低要求
操作系统 无最低要求

JSF 应用程序开发的环境搭建

按照以下步骤设置您的环境,开始进行 JSF 应用程序开发。

步骤 1:验证您的机器上是否已安装 Java

打开控制台并执行以下 Java 命令。

操作系统 任务 命令
Windows 打开命令控制台 c:\> java -version
Linux 打开命令终端 $ java -version
Mac 打开终端 machine:~ joseph$ java -version

让我们验证所有操作系统的输出 -

操作系统 生成输出
Windows

java version "1.6.0_21"

Java(TM) SE Runtime Environment (build 1.6.0_21-b07)

Java HotSpot(TM) Client VM (build 17.0-b17, mixed mode, sharing)

Linux

java version "1.6.0_21"

Java(TM) SE Runtime Environment (build 1.6.0_21-b07)

Java HotSpot(TM) Client VM (build 17.0-b17, mixed mode, sharing)

Mac

java version "1.6.0_21"

Java(TM) SE Runtime Environment (build 1.6.0_21-b07)

Java HotSpot(TM)64-Bit Server VM (build 17.0-b17, mixed mode, sharing)

步骤 2:设置 Java 开发工具包 (JDK)

如果您尚未安装 Java,则可以从 Oracle 的 Java 网站安装 Java 软件开发工具包 (SDK) - Java SE 下载。您将在下载的文件中找到安装 JDK 的说明,请按照给定的说明安装和配置设置。最后,设置 PATH 和 JAVA_HOME 环境变量以引用包含 java 和 javac 的目录,通常分别为 java_install_dir/bin 和 java_install_dir。

设置 JAVA_HOME 环境变量以指向 Java 安装在您机器上的基本目录位置。

例如 -

操作系统 输出
Windows 将环境变量 JAVA_HOME 设置为 C:\Program Files\Java\jdk1.6.0_21
Linux Export JAVA_HOME=/usr/local/java-current
Mac Export JAVA_HOME=/Library/Java/Home

将 Java 编译器位置追加到系统路径。

操作系统 输出
Windows 将字符串 ;%JAVA_HOME%\bin 追加到系统变量 Path 的末尾。
Linux Export PATH=$PATH:$JAVA_HOME/bin/
Mac 无需操作

或者,如果您使用集成开发环境 (IDE)(如 Borland JBuilder、Eclipse、IntelliJ IDEA 或 Sun ONE Studio),请编译并运行一个简单的程序以确认 IDE 知道您安装 Java 的位置。否则,请根据 IDE 的给定文档进行正确的设置。

步骤 3:设置 Eclipse IDE

本教程中的所有示例均使用 Eclipse IDE 编写。因此,我们建议您在您的机器上安装最新版本的 Eclipse,具体取决于您的操作系统。

要安装 Eclipse IDE,请从 https://www.eclipse.org/downloads/ 下载带有 WTP 支持的最新 Eclipse 二进制文件。下载安装程序后,将其解压缩到方便的位置。例如,在 Windows 上的 C:\eclipse 中,或在 Linux/Unix 上的 /usr/local/eclipse 中,最后适当地设置 PATH 变量。

可以通过在 Windows 机器上执行以下命令启动 Eclipse,或者您可以简单地双击 eclipse.exe

%C:\eclipse\eclipse.exe

可以通过在 Unix(Solaris、Linux 等)机器上执行以下命令启动 Eclipse -

$/usr/local/eclipse/eclipse

启动成功后,如果一切正常,它将显示以下结果。

Eclipse Home page

*注意 - 使用以下 Eclipse 软件更新站点将 m2eclipse 插件安装到 Eclipse 中

m2eclipse 插件 - https://m2eclipse.sonatype.org/update/

此插件使开发人员能够在 Eclipse 中使用嵌入式/外部 Maven 安装运行 Maven 命令。

步骤 4:下载 Maven 归档文件

https://maven.apache.org/download.html 下载 Maven 2.2.1

操作系统 归档文件名
Windows apache-maven-2.0.11-bin.zip
Linux apache-maven-2.0.11-bin.tar.gz
Mac apache-maven-2.0.11-bin.tar.gz

步骤 5:解压缩 Maven 归档文件

将归档文件解压缩到您希望安装 Maven 2.2.1 的目录中。子目录 apache-maven-2.2.1 将从归档文件中创建。

操作系统 位置(根据您的安装情况可能有所不同)
Windows C:\Program Files\Apache Software Foundation\apache-maven-2.2.1
Linux /usr/local/apache-maven
Mac /usr/local/apache-maven

步骤 6:设置 Maven 环境变量

将 M2_HOME、M2、MAVEN_OPTS 添加到环境变量中。

操作系统 输出
Windows

使用系统属性设置环境变量。

M2_HOME=C:\Program Files\Apache Software Foundation\apachemaven-2.2.1

M2=%M2_HOME%\bin

MAVEN_OPTS=-Xms256m -Xmx512m

Linux

打开命令终端并设置环境变量。

export M2_HOME=/usr/local/apache-maven/apache-maven-2.2.1

export M2=%M2_HOME%\bin

export MAVEN_OPTS=-Xms256m -Xmx512m

Mac

打开命令终端并设置环境变量。

export M2_HOME=/usr/local/apache-maven/apache-maven-2.2.1

export M2=%M2_HOME%\bin

export MAVEN_OPTS=-Xms256m -Xmx512m

步骤 7:将 Maven bin 目录位置添加到系统路径

现在将 M2 变量追加到系统路径。

操作系统 输出
Windows 将字符串 ;%M2% 追加到系统变量 Path 的末尾。
Linux export PATH=$M2:$PATH
Mac export PATH=$M2:$PATH

步骤 8:验证 Maven 安装。

打开控制台,执行以下 mvn 命令。

操作系统 任务 命令
Windows 打开命令控制台 c:\> mvn --version
Linux 打开命令终端 $ mvn --version
Mac 打开终端 machine:~ joseph$ mvn --version

最后,验证上述命令的输出,它应如以下表格所示。

操作系统 输出
Windows

Apache Maven 2.2.1 (r801777; 2009-08-07 00:46:01+0530)

Java version: 1.6.0_21

Java home: C:\Program Files\Java\jdk1.6.0_21\jre

Linux

Apache Maven 2.2.1 (r801777; 2009-08-07 00:46:01+0530)

Java version: 1.6.0_21

Java home: C:\Program Files\Java\jdk1.6.0_21\jre

Mac

Apache Maven 2.2.1 (r801777; 2009-08-07 00:46:01+0530)

Java version: 1.6.0_21

Java home: C:\Program Files\Java\jdk1.6.0_21\jre

步骤 9:设置 Apache Tomcat

您可以从 https://tomcat.net.cn/ 下载最新版本的 Tomcat。下载安装程序后,将其解压缩到方便的位置。例如,在 Windows 上的 C:\apache-tomcat-6.0.33 中,或在 Linux/Unix 上的 /usr/local/apache-tomcat-6.0.33 中,并设置指向安装位置的 CATALINA_HOME 环境变量。

可以通过在 Windows 机器上执行以下命令启动 Tomcat,或者您可以简单地双击 startup.bat

%CATALINA_HOME%\bin\startup.bat 
or 
C:\apache-tomcat-6.0.33\bin\startup.bat

可以通过在 Unix(Solaris、Linux 等)机器上执行以下命令启动 Tomcat。

$CATALINA_HOME/bin/startup.sh 
or 
/usr/local/apache-tomcat-6.0.33/bin/startup.sh

启动成功后,可以通过访问 https://127.0.0.1:8080/ 来使用 Tomcat 附带的默认 Web 应用程序。如果一切正常,它将显示以下结果。

Tomcat Home page

有关配置和运行 Tomcat 的更多信息,请参阅此处包含的文档以及 Tomcat 网站 - https://tomcat.net.cn

可以通过在 Windows 机器上执行以下命令停止 Tomcat。

%CATALINA_HOME%\bin\shutdown 
or 
C:\apache-tomcat-5.5.29\bin\shutdown 

可以通过在 Unix(Solaris、Linux 等)机器上执行以下命令停止 Tomcat。

$CATALINA_HOME/bin/shutdown.sh 
or 
/usr/local/apache-tomcat-5.5.29/bin/shutdown.sh

JSF - 架构

JSF 技术是一个用于开发、构建服务器端用户界面组件并在 Web 应用程序中使用它们的框架。JSF 技术基于模型视图控制器 (MVC) 架构来分离逻辑和表示。

什么是 MVC 设计模式?

MVC 设计模式使用三个独立的模块设计应用程序 -

序号 模块及描述
1

模型

承载数据和逻辑

2

视图

显示用户界面

3

控制器

处理应用程序。

MVC 设计模式的目的是分离模型和表示,使开发人员能够专注于其核心技能并更清晰地协作。

Web 设计师只需专注于视图层,而不是模型层和控制器层。开发人员可以更改模型的代码,通常不需要更改视图层。控制器用于处理用户操作。在此过程中,模型层和视图层可能会发生变化。

JSF 架构

JSF 应用程序类似于任何其他基于 Java 技术的 Web 应用程序;它在 Java servlet 容器中运行,并且包含 -

  • 作为模型的 JavaBeans 组件,包含特定于应用程序的功能和数据

  • 用于表示事件处理程序和验证器的自定义标签库

  • 用于渲染 UI 组件的自定义标签库

  • 表示为服务器上状态对象的用户界面组件

  • 服务器端辅助类

  • 验证器、事件处理程序和导航处理程序

  • 用于配置应用程序资源的应用程序配置资源文件

JSF Architecture

可以使用控制器执行用户操作。用户界面可以由网页作者创建,业务逻辑可以由托管 Bean 利用。

JSF 提供了几种渲染单个组件的机制。由网页设计师选择所需的表示形式,应用程序开发人员无需知道使用哪种机制来渲染 JSF UI 组件。

JSF - 生命周期

JSF 应用程序生命周期包含六个阶段,如下所示 -

  • 还原视图阶段
  • 应用请求值阶段;处理事件
  • 处理验证阶段;处理事件
  • 更新模型值阶段;处理事件
  • 调用应用程序阶段;处理事件
  • 渲染响应阶段
JSF Life Cycle

这六个阶段显示了 JSF 处理表单的顺序。列表按其可能的执行顺序显示阶段,每个阶段都进行事件处理。

阶段 1:还原视图

一旦单击链接或按钮并且 JSF 接收到请求,JSF 就会开始还原视图阶段。

在此阶段,JSF 构建视图,将事件处理程序和验证器连接到 UI 组件,并将视图保存在 FacesContext 实例中。FacesContext 实例现在将包含处理请求所需的所有信息。

阶段 2:应用请求值

创建/还原组件树后,组件树中的每个组件都使用 decode 方法从请求参数中提取其新值。组件存储此值。如果转换失败,则会生成错误消息并将其排队到 FacesContext 中。此消息将在渲染响应阶段与任何验证错误一起显示。

如果任何解码方法事件监听器在当前 FacesContext 实例上调用 renderResponse,则 JSF 将进入渲染响应阶段。

阶段 3:处理验证

在此阶段,JSF 处理组件树上注册的所有验证器。它检查组件属性规则以进行验证,并将这些规则与为组件存储的本地值进行比较。

如果本地值无效,则 JSF 会将错误消息添加到 FacesContext 实例中,生命周期将前进到渲染响应阶段,并再次显示包含错误消息的同一页面。

阶段 4:更新模型值

在 JSF 检查数据有效后,它会遍历组件树并将相应的服务器端对象属性设置为组件的本地值。JSF 将更新与输入组件的值属性相对应的 Bean 属性。

如果任何 updateModels 方法在当前 FacesContext 实例上调用 renderResponse,则 JSF 将进入渲染响应阶段。

阶段 5:调用应用程序

在此阶段,JSF 处理任何应用程序级事件,例如提交表单/链接到另一个页面。

阶段 6:渲染响应

在此阶段,如果应用程序使用 JSP 页面,JSF 会要求容器/应用程序服务器渲染页面。对于初始请求,页面上表示的组件将作为 JSP 容器执行页面时添加到组件树中。如果不是初始请求,则组件树已构建,因此无需再次添加组件。无论哪种情况,组件都将在 JSP 容器/应用程序服务器遍历页面中的标签时自行渲染。

渲染视图内容后,将保存响应状态,以便后续请求可以访问它,并且它可用于恢复视图阶段。

JSF - 第一个应用程序

要创建简单的 JSF 应用程序,我们将使用 maven-archetype-webapp 插件。在以下示例中,我们将在 C:\JSF 文件夹中创建一个基于 Maven 的 Web 应用程序项目。

创建项目

让我们打开命令控制台,转到C:\ > JSF目录并执行以下mvn命令。

C:\JSF>mvn archetype:create  
-DgroupId = com.tutorialspoint.test  
-DartifactId = helloworld  
-DarchetypeArtifactId = maven-archetype-webapp 

Maven 将开始处理,并将创建完整的 Java Web 应用程序项目结构。

[INFO] Scanning for projects... 
[INFO] Searching repository for plugin with prefix: 'archetype'. 
[INFO] ------------------------------------------------------------- 
[INFO] Building Maven Default Project 
[INFO]    task-segment: [archetype:create] (aggregator-style) 
[INFO] ------------------------------------------------------------- 
[INFO] [archetype:create {execution: default-cli}] 
[INFO] Defaulting package to group ID: com.tutorialspoint.test 
[INFO] artifact org.apache.maven.archetypes:maven-archetype-webapp:  
checking for updates from central 
[INFO] ------------------------------------------------------------- 
[INFO] Using following parameters for creating project  
from Old (1.x) Archetype: maven-archetype-webapp:RELEASE 
[INFO] ------------------------------------------------------------- 
[INFO] Parameter: groupId, Value: com.tutorialspoint.test 
[INFO] Parameter: packageName, Value: com.tutorialspoint.test 
[INFO] Parameter: package, Value: com.tutorialspoint.test 
[INFO] Parameter: artifactId, Value: helloworld 
[INFO] Parameter: basedir, Value: C:\JSF 
[INFO] Parameter: version, Value: 1.0-SNAPSHOT 
[INFO] project created from Old (1.x) Archetype in dir: 
C:\JSF\helloworld 
[INFO] ------------------------------------------------------------- 
[INFO] BUILD SUCCESSFUL 
[INFO] ------------------------------------------------------------- 
[INFO] Total time: 7 seconds 
[INFO] Finished at: Mon Nov 05 16:05:04 IST 2012 
[INFO] Final Memory: 12M/84M 
[INFO] ------------------------------------------------------------- 

现在转到 C:/JSF 目录。您将看到一个创建的 Java Web 应用程序项目,名为 helloworld(如 artifactId 中指定)。Maven 使用以下屏幕截图所示的标准目录布局。

Java web application project structure

使用以上示例,我们可以理解以下关键概念。

序号 文件夹结构和描述
1

helloworld

包含 src 文件夹和 pom.xml

2

src/main/wepapp

包含 WEB-INF 文件夹和 index.jsp 页面

3

src/main/resources

它包含图像/属性文件(在以上示例中,我们需要手动创建此结构)

向项目添加 JSF 功能

添加以下 JSF 依赖项。

<dependencies>
   <dependency>
      <groupId>com.sun.faces</groupId>
      <artifactId>jsf-api</artifactId>
      <version>2.1.7</version>
   </dependency>
	
   <dependency>
      <groupId>com.sun.faces</groupId>
      <artifactId>jsf-impl</artifactId>
      <version>2.1.7</version>
   </dependency>
	
</dependencies>  

完整的 POM.xml

<project xmlns = "http://maven.apache.org/POM/4.0.0" 
   xmlns:xsi = "http://www.w3.org/2001/XMLSchema-instance"
   xsi:schemaLocation = "http://maven.apache.org/POM/4.0.0
   http://maven.apache.org/maven-v4_0_0.xsd">
	
   <modelVersion>4.0.0</modelVersion>
   <groupId>com.tutorialspoint.test</groupId>
   <artifactId>helloworld</artifactId>
   <packaging>war</packaging>
   <version>1.0-SNAPSHOT</version>
   <name>helloworld Maven Webapp</name>
   <url>http://maven.apache.org</url>
	
   <dependencies>
      <dependency>
         <groupId>junit</groupId>
         <artifactId>junit</artifactId>
         <version>3.8.1</version>
         <scope>test</scope>
      </dependency>
		
      <dependency>
         <groupId>com.sun.faces</groupId>
         <artifactId>jsf-api</artifactId>
         <version>2.1.7</version>
      </dependency>
		
      <dependency>
         <groupId>com.sun.faces</groupId>
         <artifactId>jsf-impl</artifactId>
         <version>2.1.7</version>
      </dependency>
		
   </dependencies>
	
   <build>
      <finalName>helloworld</finalName>
      <plugins>
         <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-compiler-plugin</artifactId>
            <version>2.3.1</version>
				
            <configuration>
               <source>1.6</source>
               <target>1.6</target>
            </configuration>
         </plugin>
      </plugins>
   
   </build>		
</project>

准备 Eclipse 项目

让我们打开命令控制台。转到C:\ > JSF > helloworld目录并执行以下mvn命令。

C:\JSF\helloworld>mvn eclipse:eclipse -Dwtpversion = 2.0

Maven 将开始处理,创建 Eclipse 准备就绪的项目,并将添加 wtp 功能。

Downloading: http://repo.maven.apache.org/org/apache/maven/plugins/
maven-compiler-plugin/2.3.1/maven-compiler-plugin-2.3.1.pom
5K downloaded  (maven-compiler-plugin-2.3.1.pom)
Downloading: http://repo.maven.apache.org/org/apache/maven/plugins/
maven-compiler-plugin/2.3.1/maven-compiler-plugin-2.3.1.jar
29K downloaded  (maven-compiler-plugin-2.3.1.jar)
[INFO] Searching repository for plugin with prefix: 'eclipse'.
[INFO] ------------------------------------------------------------
[INFO] Building helloworld Maven Webapp
[INFO]    task-segment: [eclipse:eclipse]
[INFO] ------------------------------------------------------------
[INFO] Preparing eclipse:eclipse
[INFO] No goals needed for project - skipping
[INFO] [eclipse:eclipse {execution: default-cli}]
[INFO] Adding support for WTP version 2.0.
[INFO] Using Eclipse Workspace: null
[INFO] Adding default classpath container: org.eclipse.jdt.
launching.JRE_CONTAINER
Downloading: http://repo.maven.apache.org/
com/sun/faces/jsf-api/2.1.7/jsf-api-2.1.7.pom
12K downloaded  (jsf-api-2.1.7.pom)
Downloading: http://repo.maven.apache.org/
com/sun/faces/jsf-impl/2.1.7/jsf-impl-2.1.7.pom
10K downloaded  (jsf-impl-2.1.7.pom)
Downloading: http://repo.maven.apache.org/
com/sun/faces/jsf-api/2.1.7/jsf-api-2.1.7.jar
619K downloaded  (jsf-api-2.1.7.jar)
Downloading: http://repo.maven.apache.org/
com/sun/faces/jsf-impl/2.1.7/jsf-impl-2.1.7.jar
1916K downloaded  (jsf-impl-2.1.7.jar)
[INFO] Wrote settings to C:\JSF\helloworld\.settings\
org.eclipse.jdt.core.prefs
[INFO] Wrote Eclipse project for "helloworld" to C:\JSF\helloworld.
[INFO]
[INFO] -----------------------------------------------------------
[INFO] BUILD SUCCESSFUL
[INFO] -----------------------------------------------------------
[INFO] Total time: 6 minutes 7 seconds
[INFO] Finished at: Mon Nov 05 16:16:25 IST 2012
[INFO] Final Memory: 10M/89M
[INFO] -----------------------------------------------------------

在 Eclipse 中导入项目

以下是步骤 -

  • 使用导入向导在 Eclipse 中导入项目。

  • 转到文件→导入...→将现有项目导入工作区

  • 选择 helloworld 的根目录。

  • 保持将项目复制到工作区处于选中状态。

  • 单击“完成”按钮。

  • Eclipse 将导入并将项目复制到其工作区C:\→项目→数据→工作区

Eclipse project structure

在 web.xml 中配置 Faces Servlet

webapp→WEB-INF文件夹中找到 web.xml 并按如下所示更新它。

<?xml version = "1.0" encoding = "UTF-8"?>
<web-app xmlns:xsi = "http://www.w3.org/2001/XMLSchema-instance"
   xmlns = "http://java.sun.com/xml/ns/javaee" 
   xmlns:web = "http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
   xsi:schemaLocation = "http://java.sun.com/xml/ns/javaee 
   http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
   id = "WebApp_ID" version="2.5">
	
   <welcome-file-list>
      <welcome-file>faces/home.xhtml</welcome-file>
   </welcome-file-list>
	
   <!-- 
      FacesServlet is main servlet responsible to handle all request. 
      It acts as central controller.
      This servlet initializes the JSF components before the JSP is displayed.
   -->
	
   <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>/faces/*</url-pattern>
   </servlet-mapping>
	
   <servlet-mapping>
      <servlet-name>Faces Servlet</servlet-name>
      <url-pattern>*.jsf</url-pattern>
   </servlet-mapping>
	
   <servlet-mapping>
      <servlet-name>Faces Servlet</servlet-name>
      <url-pattern>*.faces</url-pattern>
   </servlet-mapping>
	
   <servlet-mapping>
      <servlet-name>Faces Servlet</servlet-name>
      <url-pattern>*.xhtml</url-pattern>
   </servlet-mapping>
	
</web-app>

创建一个托管 Bean

src→main→java 作为 com→tutorialspoint→test下创建一个包结构。在此包中创建 HelloWorld.java 类。按如下所示更新HelloWorld.java的代码。

package com.tutorialspoint.test;

import javax.faces.bean.ManagedBean;

@ManagedBean(name = "helloWorld", eager = true)
public class HelloWorld {
   
   public HelloWorld() {
      System.out.println("HelloWorld started!");
   }
	
   public String getMessage() {
      return "Hello World!";
   }
}

创建一个 JSF 页面

webapp文件夹下创建一个页面 home.xhtml。按如下所示更新home.xhtml的代码。

<!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">
   <head>
      <title>JSF Tutorial!</title>
   </head>

   <body>
      #{helloWorld.getMessage()}
   </body>
</html>

构建项目

以下是步骤。

  • 在 Eclipse 中选择 helloworld 项目

  • 使用“运行方式”向导

  • 选择运行方式→Maven package

  • Maven 将开始构建项目,并在C:\→项目→数据→工作区→helloworld→target文件夹下创建 helloworld.war。

[INFO] Scanning for projects...
[INFO] -----------------------------------------------------
[INFO] Building helloworld Maven Webapp
[INFO] 
[INFO] Id: com.tutorialspoint.test:helloworld:war:1.0-SNAPSHOT
[INFO] task-segment: [package]
[INFO] -----------------------------------------------------
[INFO] [resources:resources]
[INFO] Using default encoding to copy filtered resources.
[INFO] [compiler:compile]
[INFO] Nothing to compile - all classes are up to date
[INFO] [resources:testResources]
[INFO] Using default encoding to copy filtered resources.
[INFO] [compiler:testCompile]
[INFO] No sources to compile
[INFO] [surefire:test]
[INFO] Surefire report directory: 
C:\Projects\Data\WorkSpace\helloworld\target\surefire-reports

-------------------------------------------------------
 T E S T S
-------------------------------------------------------
There are no tests to run.

Results :

Tests run: 0, Failures: 0, Errors: 0, Skipped: 0

[INFO] [war:war]
[INFO] Packaging webapp
[INFO] Assembling webapp[helloworld] in
[C:\Projects\Data\WorkSpace\helloworld\target\helloworld]
[INFO] Processing war project
[INFO] Webapp assembled in[150 msecs]
[INFO] Building war: 
C:\Projects\Data\WorkSpace\helloworld\target\helloworld.war
[INFO] ------------------------------------------------
[INFO] BUILD SUCCESSFUL
[INFO] ------------------------------------------------
[INFO] Total time: 3 seconds
[INFO] Finished at: Mon Nov 05 16:34:46 IST 2012
[INFO] Final Memory: 2M/15M
[INFO] ------------------------------------------------

部署 WAR 文件

以下是步骤。

  • 停止 Tomcat 服务器。

  • 将 helloworld.war 文件复制到Tomcat 安装目录→webapps 文件夹

  • 启动 Tomcat 服务器。

  • 查看 webapps 目录内部,应该创建了一个名为 helloworld 的文件夹。

  • 现在 helloworld.war 已成功部署在 Tomcat Webserver 根目录中。

运行应用程序

在 Web 浏览器中输入 URL:https://127.0.0.1:8080/helloworld/home.jsf以启动应用程序。

服务器名称 (localhost) 和端口 (8080) 可能因您的 Tomcat 配置而异。

JSF Application Result

JSF - 托管 Bean

托管 Bean 是一个使用 JSF 注册的常规 Java Bean 类。换句话说,托管 Bean 是由 JSF 框架管理的 Java Bean。托管 Bean 包含 getter 和 setter 方法、业务逻辑,甚至是一个支持 Bean(一个包含所有 HTML 表单值的 Bean)。

托管 Bean 充当 UI 组件的模型。可以从 JSF 页面访问托管 Bean。

JSF 1.2中,托管 Bean 必须在 JSF 配置文件(如 facesconfig.xml)中注册它。从JSF 2.0开始,可以使用注释轻松注册托管 Bean。这种方法将 Bean 及其注册保留在一个位置,因此易于管理。

使用 XML 配置

<managed-bean>
   <managed-bean-name>helloWorld</managed-bean-name>
   <managed-bean-class>com.tutorialspoint.test.HelloWorld</managed-bean-class>
   <managed-bean-scope>request</managed-bean-scope>
</managed-bean> 

<managed-bean>
   <managed-bean-name>message</managed-bean-name>
   <managed-bean-class>com.tutorialspoint.test.Message</managed-bean-class>
   <managed-bean-scope>request</managed-bean-scope>
</managed-bean> 

使用注释

@ManagedBean(name = "helloWorld", eager = true)
@RequestScoped
public class HelloWorld {
   @ManagedProperty(value = "#{message}")
   private Message message;
   ...
}

@ManagedBean 注释

@ManagedBean将 Bean 标记为托管 Bean,其名称在 name 属性中指定。如果未指定 name 属性,则托管 Bean 名称将默认为完整限定类名的类名部分。在我们的例子中,它将是 helloWorld。

另一个重要的属性是eager。如果 eager = "true",则在首次请求托管 Bean 之前创建它,否则使用“延迟”初始化,其中仅在请求 Bean 时创建它。

作用域注释

作用域注释设置托管 Bean 将放置其中的作用域。如果未指定作用域,则 Bean 将默认为请求作用域。下表简要讨论了每个作用域。

序号 作用域和描述
1

@RequestScoped

Bean 的生命周期与 HTTP 请求-响应的生命周期相同。它在 HTTP 请求时创建,并在与 HTTP 请求关联的 HTTP 响应完成时销毁。

2

@NoneScoped

Bean 的生命周期与单个 EL 评估相同。它在 EL 评估时创建,并在 EL 评估后立即销毁。

3

@ViewScoped

Bean 的生命周期与用户在浏览器窗口/选项卡中与同一 JSF 视图交互的时间相同。它在 HTTP 请求时创建,并在用户回发到不同视图时销毁。

4

@SessionScoped

Bean 的生命周期与 HTTP 会话的生命周期相同。它在会话中涉及此 Bean 的第一个 HTTP 请求时创建,并在 HTTP 会话失效时销毁。

5

@ApplicationScoped

Bean 的生命周期与 Web 应用程序的生命周期相同。它在应用程序中涉及此 Bean 的第一个 HTTP 请求时创建(或在 Web 应用程序启动并且在 @ManagedBean 中设置了 eager=true 属性时),并在 Web 应用程序关闭时销毁。

6

@CustomScoped

Bean 的生命周期与为该作用域创建的自定义 Map 中的 Bean 条目相同。

@ManagedProperty 注释

JSF 是一个简单的静态依赖注入 (DI) 框架。使用@ManagedProperty注释,可以在另一个托管 Bean 中注入托管 Bean 的属性。

示例应用程序

让我们创建一个测试 JSF 应用程序来测试托管 Bean 的上述注释。

步骤 描述
1 JSF - 创建应用程序章节中说明的包com.tutorialspoint.test下创建一个名为helloworld的项目。
2 修改HelloWorld.java,如下所述。保持其余文件不变。
3 在包com.tutorialspoint.test下创建Message.java,如下所述。
4 编译并运行应用程序以确保业务逻辑按要求工作。
5 最后,以 war 文件的形式构建应用程序,并将其部署到 Apache Tomcat Webserver 中。
6 使用下面最后一步中说明的适当 URL 启动您的 Web 应用程序。

HelloWorld.java

package com.tutorialspoint.test;

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

@ManagedBean(name = "helloWorld", eager = true)
@RequestScoped
public class HelloWorld {
   @ManagedProperty(value = "#{message}")
   private Message messageBean;
   private String message;
   
   public HelloWorld() {
      System.out.println("HelloWorld started!");   
   }
   
   public String getMessage() {
      
      if(messageBean != null) {
         message = messageBean.getMessage();
      }       
      return message;
   }
   
   public void setMessageBean(Message message) {
      this.messageBean = message;
   }
}

Message.java

package com.tutorialspoint.test;

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

@ManagedBean(name = "message", eager = true)
@RequestScoped
public class Message {
   private String message = "Hello World!";
	
   public String getMessage() {
      return message;
   }
   public void setMessage(String message) {
      this.message = message;
   }
}

home.xhtml

<!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">
   <head>
      <title>JSF Tutorial!</title>
   </head>
   
   <body>
      #{helloWorld.message}
   </body>
</html>

准备好所有更改后,让我们像在 JSF - 创建应用程序章节中那样编译和运行应用程序。如果您的应用程序一切正常,这将产生以下结果。

JSF Managed Beans

JSF - 页面导航

导航规则是由 JSF 框架提供的那些规则,描述了单击按钮或链接时要显示哪个视图。

导航规则可以在名为 faces-config.xml 的 JSF 配置文件中定义。它们可以在托管 Bean 中定义。

导航规则可以包含基于其显示结果视图的条件。JSF 2.0 还提供隐式导航,在这种情况下,不需要像这样定义导航规则。

隐式导航

JSF 2.0 提供名为隐式导航自动视图页面解析器机制。在这种情况下,您只需要在 action 属性中放置视图名称,JSF 将自动在已部署的应用程序中搜索正确的视图页面。

JSF Home Page

JSF 页面中的自动导航

在任何 JSF UI 组件的 action 属性中设置视图名称。

<h:form>
   <h3>Using JSF outcome</h3>
   <h:commandButton action = "page2" value = "Page2" />
</h:form>

在这里,当单击Page2按钮时,JSF 将解析视图名称page2作为 page2.xhtml 扩展名,并在当前目录中找到相应的视图文件page2.xhtml

JSF Page 2

托管 Bean 中的自动导航

在托管 Bean 中定义一个方法以返回视图名称。

@ManagedBean(name = "navigationController", eager = true)
@RequestScoped

public class NavigationController implements Serializable {
   public String moveToPage1() {
      return "page1";
   }
}

使用托管 Bean 在任何 JSF UI 组件的 action 属性中获取视图名称。

<h:form> 
   <h3> Using Managed Bean</h3>  
   <h:commandButton action = "#{navigationController.moveToPage1}" 
   value = "Page1" /glt; 
</h:form> 

在这里,当单击Page1按钮时,JSF 将解析视图名称page1作为 page1.xhtml 扩展名,并在当前目录中找到相应的视图文件page1.xhtml

JSF Page 1

条件导航

使用托管 Bean,我们可以非常轻松地控制导航。查看托管 Bean 中的以下代码。

JSF Conditional Navigation

@ManagedBean(name = "navigationController", eager = true)
@RequestScoped

public class NavigationController implements Serializable {
   //this managed property will read value from request parameter pageId
   @ManagedProperty(value = "#{param.pageId}")
   private String pageId;

   //condional navigation based on pageId
   //if pageId is 1 show page1.xhtml,
   //if pageId is 2 show page2.xhtml
   //else show home.xhtml
   
   public String showPage() {
      if(pageId == null) {
         return "home";
      }
      
      if(pageId.equals("1")) {
         return "page1";
      }else if(pageId.equals("2")) {
         return "page2";
      }else {
         return "home";
      }
   }
}

在 JSF UI 组件中将 pageId 作为请求参数传递。

<h:form>
   <h:commandLink action = "#{navigationController.showPage}" value = "Page1">
      <f:param name = "pageId" value = "1" />
   </h:commandLink>
   <h:commandLink action = "#{navigationController.showPage}" value = "Page2">
      <f:param name = "pageId" value = "2" />
   </h:commandLink>
   <h:commandLink action = "#{navigationController.showPage}" value = "Home">
      <f:param name = "pageId" value = "3" />
   </h:commandLink>
</h:form>

在这里,当单击“Page1”按钮时。

  • JSF 将创建一个带参数 pageId = 1 的请求

  • 然后 JSF 将此参数传递到导航控制器的托管属性 pageId

  • 现在调用 navigationController.showPage(),它将在检查 pageId 后将视图返回为 page1

  • JSF 将解析视图名称 page1 为 page1.xhtml 扩展名

  • 在当前目录中找到相应的视图文件 page1.xhtml

JSF Page 1

基于 from-action 的导航解析

即使受管 Bean 中的不同方法返回相同的视图名称,JSF 也提供了导航解析选项。

JSF From Action

查看受管 Bean 中的以下代码。

public String processPage1() { 
   return "page"; 
} 
public String processPage2() { 
   return "page"; 
} 

要解析视图,请在faces-config.xml中定义以下导航规则

<navigation-rule> 
   <from-view-id>home.xhtml</from-view-id> 
   
   <navigation-case> 
      <from-action>#{navigationController.processPage1}</from-action> 
      <from-outcome>page</from-outcome> 
      <to-view-id>page1.jsf</to-view-id> 
   </navigation-case> 
   
   <navigation-case> 
      <from-action>#{navigationController.processPage2}</from-action> 
      <from-outcome>page</from-outcome> 
      <to-view-id>page2.jsf</to-view-id> 
   </navigation-case> 

</navigation-rule> 

这里,当单击 Page1 按钮时 -

  • navigationController.processPage1()被调用,它将返回视图 page

  • JSF 将解析视图名称page1,因为视图名称为page,并且faces-config中的from-action为navigationController.processPage1

  • 在当前目录中找到相应的视图文件page1.xhtml

JSF Page 1

转发与重定向

JSF 默认情况下在导航到另一个页面时执行服务器页面转发,并且应用程序的 URL 不会更改。

要启用页面重定向,请在视图名称的末尾附加faces-redirect=true

JSF Forward vs Redirect
<h:form>
   <h3>Forward</h3>
   <h:commandButton action = "page1" value = "Page1" />
   <h3>Redirect</h3>
   <h:commandButton action = "page1?faces-redirect = true" value = "Page1" />
</h:form>

这里,当单击转发下的Page1按钮时,您将获得以下结果。

JSF Page 1 Forward

这里,当单击重定向下的Page1按钮时,您将获得以下结果。

JSF Page 1 Redirect

示例应用程序

让我们创建一个测试 JSF 应用程序来测试上述所有导航示例。

步骤 描述
1 JSF - 创建应用程序章节中说明的基础上,创建一个名为helloworld的项目,放在package com.tutorialspoint.test下。
2 package com.tutorialspoint.test下创建NavigationController.java,如下所示。
3 WEB-INF文件夹下创建faces-config.xml并更新其内容,如下所示。
4 更新WEB-INF文件夹下的web.xml,如下所示。
5 webapp文件夹下创建page1.xhtmlpage2.xhtml并修改home.xhtml,如下所示。
6 编译并运行应用程序以确保业务逻辑按要求工作。
7 最后,以 war 文件的形式构建应用程序,并将其部署到 Apache Tomcat Webserver 中。
8 使用下面最后一步中说明的适当 URL 启动您的 Web 应用程序。

NavigationController.java

package com.tutorialspoint.test;
  
import java.io.Serializable;  

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

@ManagedBean(name = "navigationController", eager = true) 
@RequestScoped 
public class NavigationController implements Serializable {  
   private static final long serialVersionUID = 1L;  
   @ManagedProperty(value = "#{param.pageId}")    
   private String pageId;  
   
   public String moveToPage1() {      
      return "page1";    
   }  
   
   public String moveToPage2() {       
      return "page2";    
   }  
   
   public String moveToHomePage() {      
      return "home";    
   }  
   
   public String processPage1() {       
      return "page";    
   }  
   
   public String processPage2() {       
      return "page";    
   } 
   
   public String showPage() {       
      if(pageId == null) {          
         return "home";       
      }       
      
      if(pageId.equals("1")) {          
         return "page1";       
      }else if(pageId.equals("2")) {          
         return "page2";       
      }else {          
         return "home";       
      }    
   }  
   
   public String getPageId() {       
      return pageId;    
   }  
   
   public void setPageId(String pageId) {       
      this.pageId = pageId;   
   } 
} 

faces-config.xml

<?xml version = "1.0" encoding = "UTF-8"?>

<faces-config
   xmlns = "http://java.sun.com/xml/ns/javaee"
   xmlns:xsi = "http://www.w3.org/2001/XMLSchema-instance"
   xsi:schemaLocation = "http://java.sun.com/xml/ns/javaee
   http://java.sun.com/xml/ns/javaee/web-facesconfig_2_0.xsd"
   version = "2.0">
   
   <navigation-rule>
      <from-view-id>home.xhtml</from-view-id>
      <navigation-case>
         <from-action>#{navigationController.processPage1}</from-action>
         <from-outcome>page</from-outcome>
         <to-view-id>page1.jsf</to-view-id>
      </navigation-case>
      <navigation-case>
         <from-action>#{navigationController.processPage2}</from-action>
         <from-outcome>page</from-outcome>
         <to-view-id>page2.jsf</to-view-id>
      </navigation-case>
   </navigation-rule>

</faces-config>

web.xml

<!DOCTYPE web-app PUBLIC
   "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN"
   "http://java.sun.com/dtd/web-app_2_3.dtd" >

<web-app>
   <display-name>Archetype Created Web Application</display-name>

   <context-param>
      <param-name>javax.faces.PROJECT_STAGE</param-name>
      <param-value>Development</param-value>
   </context-param>
   <context-param>
      <param-name>javax.faces.CONFIG_FILES</param-name>
      <param-value>/WEB-INF/faces-config.xml</param-value>
   </context-param>
   
   <servlet>
      <servlet-name>Faces Servlet</servlet-name>
      <servlet-class>javax.faces.webapp.FacesServlet</servlet-class>
   </servlet>
   <servlet-mapping>
      <servlet-name>Faces Servlet</servlet-name>
      <url-pattern>*.jsf</url-pattern>
   </servlet-mapping>

</web-app>

page1.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:h = "http://java.sun.com/jsf/html">
   
   <h:body>
      <h2>This is Page1</h2>
      <h:form>
         <h:commandButton action = "home?faces-redirect = true"
            value = "Back To Home Page" />
      </h:form>
   </h:body>
</html>

page2.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:h = "http://java.sun.com/jsf/html">
   
   <h:body>
      <h2>This is Page2</h2>
      <h:form>
         <h:commandButton action = "home?faces-redirect = true"
            value = "Back To Home Page" />
      </h:form>
   </h:body>
</html>

home.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>
      <h2>Implicit Navigation</h2>
      <hr />
      
      <h:form>
         <h3>Using Managed Bean</h3>
         <h:commandButton action = "#{navigationController.moveToPage1}"
            value = "Page1" />
         <h3>Using JSF outcome</h3>
         <h:commandButton action = "page2" value = "Page2" />
      </h:form>
      <br/>
      
      <h2>Conditional Navigation</h2>
      <hr />
      <h:form>
         <h:commandLink action = "#{navigationController.showPage}"
            value="Page1">
            <f:param name = "pageId" value = "1" />
         </h:commandLink>
              
         
         <h:commandLink action = "#{navigationController.showPage}"
            value="Page2">
            <f:param name = "pageId" value = "2" />
         </h:commandLink>
              
         
         <h:commandLink action = "#{navigationController.showPage}"
            value = "Home">
            <f:param name = "pageId" value = "3" />
         </h:commandLink>
      </h:form>
      <br/>
      
      <h2>"From Action" Navigation</h2>
      <hr />
      
      <h:form>
         <h:commandLink action = "#{navigationController.processPage1}"
         value = "Page1" />
              
         <h:commandLink action = "#{navigationController.processPage2}"
         value = "Page2" />
              
      </h:form>
      <br/>
      
      <h2>Forward vs Redirection Navigation</h2>
      <hr />
      <h:form>
         <h3>Forward</h3>
         <h:commandButton action = "page1" value = "Page1" />
         <h3>Redirect</h3>
         <h:commandButton action = "page1?faces-redirect = true"
         value = "Page1" />
      </h:form>
   </h:body>
</html>

准备好所有更改后,让我们像在 JSF - 创建应用程序章节中那样编译和运行应用程序。如果您的应用程序一切正常,这将产生以下结果。

JSF Navigation

JSF - 基本标签

在本节中,您将学习各种基本 JSF 标签的类型。

JSF 提供了一个标准的 HTML 标签库。这些标签被渲染成相应的 html 输出。

对于这些标签,您需要在 html 节点中使用以下 URI 命名空间。

<html 
   xmlns = "http://www.w3.org/1999/xhtml" 
   xmlns:h = "http://java.sun.com/jsf/html">

以下是 JSF 2.0 中重要的基本标签。

序号 标签 & 描述
1 h:inputText

渲染一个类型为“text”的 HTML 输入,文本框。

2 h:inputSecret

渲染一个类型为“password”的 HTML 输入,文本框。

3 h:inputTextarea

渲染一个 HTML 文本区域字段。

4 h:inputHidden

渲染一个类型为“hidden”的 HTML 输入。

5 h:selectBooleanCheckbox

渲染一个 HTML 复选框。

6 h:selectManyCheckbox

渲染一组 HTML 复选框。

7 h:selectOneRadio

渲染一个 HTML 单选按钮。

8 h:selectOneListbox

渲染一个 HTML 单选列表框。

9 h:selectManyListbox

渲染一个 HTML 多选列表框。

10 h:selectOneMenu

渲染一个 HTML 组合框。

11 h:outputText

渲染一个 HTML 文本。

12 h:outputFormat

渲染一个 HTML 文本。它接受参数。

13 h:graphicImage

渲染一个图像。

14 h:outputStylesheet

在 HTML 输出中包含一个 CSS 样式表。

15 h:outputScript

在 HTML 输出中包含一个脚本。

16 h:commandButton

渲染一个类型为“submit”的 HTML 输入按钮。

17 h:Link

渲染一个 HTML 锚点。

18 h:commandLink

渲染一个 HTML 锚点。

19 h:outputLink

渲染一个 HTML 锚点。

20 h:panelGrid

以网格形式渲染一个 HTML 表格。

21 h:message

渲染 JSF UI 组件的消息。

22 h:messages

渲染所有 JSF UI 组件的消息。

23 f:param

将参数传递给 JSF UI 组件。

24 f:attribute

将属性传递给 JSF UI 组件。

25 f:setPropertyActionListener

设置受管 Bean 属性的值。

JSF - Facelets 标签

JSF 提供了特殊的标签来创建 Web 应用程序的通用布局,称为 Facelets 标签。这些标签提供了灵活地在一个地方管理多个页面的公共部分。

对于这些标签,您需要在 html 节点中使用以下 URI 命名空间。

<html  
   xmlns = "http://www.w3.org/1999/xhtml"  
   xmlns:ui = "http://java.sun.com/jsf/facelets">

以下是 JSF 2.0 中重要的 Facelets 标签。

序号 标签 & 描述
1 模板

我们将演示如何使用以下标签使用模板

  • <ui:insert>
  • <ui:define>
  • <ui:include>
  • <ui:composition>
2 参数

我们将演示如何使用以下标签将参数传递给模板文件

  • <ui:param>
3 自定义

我们将演示如何创建自定义标签

4 移除

我们将演示从生成的 HTML 页面中移除 JSF 代码的功能

JSF - 转换器标签

JSF 提供了内置的转换器,用于将 UI 组件的数据转换为受管 Bean 中使用的对象,反之亦然。例如,这些标签可以将文本转换为日期对象,并验证输入的格式。

对于这些标签,您需要在 html 节点中使用以下 URI 命名空间。

<html 
   xmlns = "http://www.w3.org/1999/xhtml" 
   xmlns:f = "http://java.sun.com/jsf/core">

以下是 JSF 2.0 中重要的转换器标签 -

序号 标签 & 描述
1 f:convertNumber

将字符串转换为所需格式的数字

2 f:convertDateTime

将字符串转换为所需格式的日期

3 自定义转换器

创建自定义转换器

JSF - 验证器标签

JSF 提供了内置的验证器来验证其 UI 组件。这些标签可以验证字段的长度、输入的类型,该类型可以是自定义对象。

对于这些标签,您需要在 html 节点中使用以下 URI 命名空间。

<html 
   xmlns = "http://www.w3.org/1999/xhtml" 
   xmlns:f = "http://java.sun.com/jsf/core">

以下是 JSF 2.0 中重要的验证器标签 -

序号 标签 & 描述
1 f:validateLength

验证字符串的长度

2 f:validateLongRange

验证数值的范围

3 f:validateDoubleRange

验证浮点值的范围

4 f:validateRegex

使用给定的正则表达式验证 JSF 组件

5 自定义验证器

创建自定义验证器

JSF - DataTable

JSF 提供了一个名为 DataTable 的丰富的控件来渲染和格式化 html 表格。

  • DataTable 可以迭代值集合或数组以显示数据。

  • DataTable 提供了以简单的方式修改其数据的属性。

HTML 标题

<html 
   xmlns = "http://www.w3.org/1999/xhtml"   
   xmlns:h = "http://java.sun.com/jsf/html">
</html>

以下是 JSF 2.0 中重要的 DataTable 操作 -

序号 标签 & 描述
1 显示 DataTable

如何显示 dataTable

2 添加数据

如何在 dataTable 中添加新行

3 编辑数据

如何在 dataTable 中编辑行

4 删除数据

如何在 dataTable 中删除行

5 使用 DataModel

使用 DataModel 在 dataTable 中显示行号

JSF - 复合组件

JSF 为开发人员提供了强大的功能来定义他们自己的自定义组件,这些组件可用于渲染自定义内容。

定义自定义组件

在 JSF 中定义自定义组件是一个两步过程。

步骤 描述
1a

创建 resources 文件夹。

在 resources 文件夹中使用复合命名空间创建 xhtml 文件。

1b

使用复合标签composite:interface、composite:attributecomposite:implementation来定义复合组件的内容。在composite:implementation中使用cc.attrs来获取在composite:interface中使用composite:attribute定义的变量。

步骤 1a:创建自定义组件:loginComponent.xhtml

在 resources 文件夹中创建一个名为 tutorialspoint 的文件夹,并在其中创建一个名为 loginComponent.xhtml 的文件。

在 html 标题中使用复合命名空间。

<html xmlns = "http://www.w3.org/1999/xhtml"   
   xmlns:h = "http://java.sun.com/jsf/html"
   xmlns:f = "http://java.sun.com/jsf/core"
   xmlns:composite = "http://java.sun.com/jsf/composite">
...
</html>

步骤 1b:使用复合标签:loginComponent.xhtml

下表描述了复合标签的使用。

序号 标签 & 描述
1

composite:interface

声明要在 composite:implementation 中使用的可配置值。

2

composite:attribute

使用此标签声明配置值。

3

composite:implementation

声明 JSF 组件。可以使用 #{cc.attrs.attribute-name} 表达式访问在 composite:interface 中定义的可配置值。

<composite:interface>
   <composite:attribute name = "usernameLabel" />
   <composite:attribute name = "usernameValue" />
</composite:interface>

<composite:implementation>
<h:form>
   #{cc.attrs.usernameLabel} : 
   <h:inputText id = "username" value = "#{cc.attrs.usernameValue}" />
</h:form>

使用自定义组件

在 JSF 中使用自定义组件是一个简单的过程。

步骤 描述
2a 创建一个 xhtml 文件并使用自定义组件的命名空间。命名空间将是http://java.sun.com/jsf/<folder-name>,其中folder-name是 resources 目录中包含自定义组件的文件夹
2b 像使用普通 JSF 标签一样使用自定义组件

步骤 2a:使用自定义命名空间:home.xhtml

<html xmlns = "http://www.w3.org/1999/xhtml"   
   xmlns:h = "http://java.sun.com/jsf/html"
   xmlns:ui = "http://java.sun.com/jsf/facelets">
   xmlns:tp = "http://java.sun.com/jsf/composite/tutorialspoint">

步骤 2b:使用自定义标签:home.xhtml 并传递值

<h:form>
   <tp:loginComponent 
      usernameLabel = "Enter User Name: " 
      usernameValue = "#{userData.name}" />
</h:form>

示例应用程序

让我们创建一个测试 JSF 应用程序来测试 JSF 中的自定义组件。

步骤 描述
1 JSF - 第一个应用程序章节中说明的基础上,创建一个名为helloworld的项目,放在package com.tutorialspoint.test下。
2 src → main文件夹下创建resources文件夹。
3 src → main → resources文件夹下创建tutorialspoint文件夹。
4 src → main → resources → tutorialspoint文件夹下创建loginComponent.xhtml文件。
5 修改UserData.java文件,如下所示。
6 修改home.xhtml,如下所示。保持其余文件不变。
7 编译并运行应用程序以确保业务逻辑按要求工作。
8 最后,以 war 文件的形式构建应用程序,并将其部署到 Apache Tomcat Webserver 中。
9 使用下面最后一步中说明的适当 URL 启动您的 Web 应用程序。

loginComponent.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:h = "http://java.sun.com/jsf/html"
   xmlns:f = "http://java.sun.com/jsf/core"
   xmlns:composite = "http://java.sun.com/jsf/composite">
   
   <composite:interface>
      <composite:attribute name = "usernameLabel" />
      <composite:attribute name = "usernameValue" />
      <composite:attribute name = "passwordLabel" />
      <composite:attribute name = "passwordValue" />
      <composite:attribute name = "loginButtonLabel" />
      <composite:attribute name = "loginButtonAction" 
         method-signature = "java.lang.String login()" />
   </composite:interface>
   
   <composite:implementation>
      <h:form>
         <h:message for = "loginPanel" style = "color:red;" />
         
         <h:panelGrid columns = "2" id = "loginPanel">
            #{cc.attrs.usernameLabel} : 
            <h:inputText id = "username" value = "#{cc.attrs.usernameValue}" />
            #{cc.attrs.passwordLabel} : 
            <h:inputSecret id = "password" value = "#{cc.attrs.passwordValue}" />
         </h:panelGrid>
         
         <h:commandButton action = "#{cc.attrs.loginButtonAction}" 
            value = "#{cc.attrs.loginButtonLabel}"/>
      </h:form>
   </composite:implementation>
</html>

UserData.java

package com.tutorialspoint.test;

import java.io.Serializable;

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

@ManagedBean(name = "userData", eager = true)
@SessionScoped
public class UserData implements Serializable {
   private static final long serialVersionUID = 1L;
   private String name;
   private String password;
   
   public String getName() {
      return name;
   }
   
   public void setName(String name) {
      this.name = name;
   }
   
   public String getPassword() {
      return password;
   }
   
   public void setPassword(String password) {
      this.password = password;
   }	
   
   public String login() {
      return "result";
   }	
}

home.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:h = "http://java.sun.com/jsf/html"
   xmlns:f = "http://java.sun.com/jsf/core"
   xmlns:tp = "http://java.sun.com/jsf/composite/tutorialspoint">
   
   <h:head>
      <title>JSF tutorial</title>		     
   </h:head>
   
   <h:body> 
      <h2>Custom Component Example</h2>
      
      <h:form>
      <tp:loginComponent 
         usernameLabel = "Enter User Name: " 
         usernameValue = "#{userData.name}" 
         passwordLabel = "Enter Password: " 
         passwordValue = "#{userData.password}"
         loginButtonLabel = "Login" 
         loginButtonAction = "#{userData.login}" />
      </h:form>
   </h:body>
</html>

完成所有更改后,让我们像在 JSF - 第一个应用程序章节中一样编译并运行应用程序。如果您的应用程序一切正常,这将产生以下结果。

JSF custom component

JSF - Ajax

AJAX 代表异步 JavaScript 和 Xml。

Ajax 是一种使用 JavaScript 的 HTTPXMLObject 将数据异步发送到服务器并从服务器接收数据的技术。因此,使用 Ajax 技术,javascript 代码与服务器交换数据,更新网页的部分内容而无需重新加载整个页面。

JSF 为进行 ajax 调用提供了极好的支持。它提供了 f:ajax 标签来处理 ajax 调用。

JSF 标签

<f:ajax execute = "input-component-name" render = "output-component-name" />

标签属性

序号 属性 & 描述
1

disabled

如果为 true,则 Ajax 行为将应用于任何父级或子级组件。如果为 false,则 Ajax 行为将被禁用。

2

Event

将调用 Ajax 请求的事件,例如“click”、“change”、“blur”、“keypress”等。

3

Execute

应包含在 Ajax 请求中的组件的 ID 的空格分隔列表。

4

Immediate

如果为“true”,则从此行为生成的事件将在“应用请求值”阶段广播。否则,这些事件将在“调用应用程序”阶段广播。

5

Listener

在 Ajax 请求期间要调用的支持 Bean 中方法的 EL 表达式。

6

Onerror

如果 Ajax 请求期间发生错误,将调用的 JavaScript 回调函数的名称。

7

Onevent

将调用的 JavaScript 回调函数的名称以处理 UI 事件。

8

Render

将在 Ajax 请求后更新的组件的 ID 的空格分隔列表。

示例应用程序

让我们创建一个测试 JSF 应用程序来测试 JSF 中的自定义组件。

步骤 描述
1 JSF - 第一个应用程序章节中说明的基础上,创建一个名为helloworld的项目,放在package com.tutorialspoint.test下。
2 修改UserData.java文件,如下所示。
3 修改home.xhtml,如下所示。保持其余文件不变。
4 编译并运行应用程序以确保业务逻辑按要求工作。
5 最后,以 war 文件的形式构建应用程序,并将其部署到 Apache Tomcat Webserver 中。
6 使用下面最后一步中说明的适当 URL 启动您的 Web 应用程序。

UserData.java

package com.tutorialspoint.test;

import java.io.Serializable;

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

@ManagedBean(name = "userData", eager = true)
@SessionScoped
public class UserData implements Serializable {
   private static final long serialVersionUID = 1L;
   private String name;
   
   public String getName() {
      return name;
   }
   
   public void setName(String name) {
      this.name = name;
   }

   public String getWelcomeMessage() {
      return "Hello " + name;
   }
}

home.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:h = "http://java.sun.com/jsf/html"
   xmlns:f = "http://java.sun.com/jsf/core"
   xmlns:tp = "http://java.sun.com/jsf/composite/tutorialspoint">
   
   <h:head>
      <title>JSF tutorial</title>
   </h:head>
   
   <h:body>
      <h2>Ajax Example</h2>
      
      <h:form>
         <h:inputText id = "inputName" value = "#{userData.name}"></h:inputText>
         <h:commandButton value = "Show Message">
            <f:ajax execute = "inputName" render = "outputMessage" />
         </h:commandButton>
         <h2><h:outputText id = "outputMessage"
            value = "#{userData.welcomeMessage != null ?
            userData.welcomeMessage : ''}"
         /></h2>
      </h:form>
   </h:body>
</html>

完成所有更改后,让我们像在 JSF - 第一个应用程序章节中一样编译并运行应用程序。如果您的应用程序一切正常,这将产生以下结果。

JSF ajax result

输入名称并按下“显示消息”按钮。您将看到以下结果,而无需页面刷新/表单提交。

JSF ajax result1

JSF - 事件处理

当用户单击 JSF 按钮或链接或更改文本字段中的任何值时,JSF UI 组件将触发一个事件,该事件将由应用程序代码处理。为了处理此类事件,需要在应用程序代码或受管 Bean 中注册事件处理程序。

当 UI 组件检查用户事件是否已发生时,它会创建相应事件类的实例并将其添加到事件列表中。然后,组件触发事件,即检查该事件的侦听器列表,并在每个侦听器或处理程序上调用事件通知方法。

JSF 还提供系统级事件处理程序,这些处理程序可用于在应用程序启动或停止时执行某些任务。

以下是 JSF 2.0 中一些重要的事件处理程序 -

序号 事件处理程序 & 描述
1 valueChangeListener

当用户在输入组件中进行更改时,将触发值更改事件。

2 actionListener

当用户单击按钮或链接组件时,将触发操作事件。

3 应用程序事件

在 JSF 生命周期期间触发的事件:PostConstructApplicationEvent、PreDestroyApplicationEvent、PreRenderViewEvent。

JSF - JDBC 集成

本文将演示如何使用 JDBC 在 JSF 中集成数据库。

以下是运行此示例所需的数据库要求。

序号 软件及描述
1 PostgreSQL 9.1

开源且轻量级的数据库

2 PostgreSQL JDBC4 驱动程序

PostgreSQL 9.1 和 JDK 1.5 或更高版本的 JDBC 驱动程序

将 PostgreSQL JDBC4 驱动程序 jar 放入 Tomcat Web 服务器的 lib 目录中。

数据库 SQL 命令

create user user1;
create database testdb with owner = user1;

CREATE TABLE IF NOT EXISTS authors (
    id int PRIMARY KEY, 
    name VARCHAR(25)
);

INSERT INTO authors(id, name) VALUES(1, 'Rob Bal');
INSERT INTO authors(id, name) VALUES(2, 'John Carter');
INSERT INTO authors(id, name) VALUES(3, 'Chris London');
INSERT INTO authors(id, name) VALUES(4, 'Truman De Bal');
INSERT INTO authors(id, name) VALUES(5, 'Emile Capote');
INSERT INTO authors(id, name) VALUES(7, 'Breech Jabber');
INSERT INTO authors(id, name) VALUES(8, 'Bob Carter');
INSERT INTO authors(id, name) VALUES(9, 'Nelson Mand');
INSERT INTO authors(id, name) VALUES(10, 'Tennant Mark');

alter user user1 with password 'user1';

grant all on authors to user1;

示例应用程序

让我们创建一个测试 JSF 应用程序来测试 JDBC 集成。

步骤 描述
1 JSF - 第一个应用程序章节中说明的基础上,创建一个名为helloworld的项目,放在package com.tutorialspoint.test下。
2 src → main文件夹下创建resources文件夹。
3 src → main → resources 文件夹下创建 css 文件夹。
4 src → main → resources → css 文件夹下创建 styles.css 文件。
5 修改 styles.css 文件,如下所述。
6 修改 pom.xml 文件,如下所述。
7 com.tutorialspoint.test 包下创建 Author.java 文件,如下所述。
8 在 com.tutorialspoint.test 包下创建 UserData.java 文件,如下所述。
9 修改home.xhtml,如下所示。保持其余文件不变。
10 编译并运行应用程序以确保业务逻辑按要求工作。
11 最后,以 war 文件的形式构建应用程序,并将其部署到 Apache Tomcat Webserver 中。
12 使用下面最后一步中说明的适当 URL 启动您的 Web 应用程序。

styles.css

.authorTable {   
   border-collapse:collapse;
   border-bottom:1px solid #000000;
}

.authorTableHeader {
   text-align:center;
   background:none repeat scroll 0 0 #B5B5B5;
   border-bottom:1px solid #000000;
   border-top:1px solid #000000;
   padding:2px;
}

.authorTableOddRow {
   text-align:center;
   background:none repeat scroll 0 0 #FFFFFFF;	
}

.authorTableEvenRow {
   text-align:center;
   background:none repeat scroll 0 0 #D3D3D3;
}

pom.xml

<project xmlns = "http://maven.apache.org/POM/4.0.0" 
   xmlns:xsi = "http://www.w3.org/2001/XMLSchema-instance"
   xsi:schemaLocation = "http://maven.apache.org/POM/4.0.0
   http://maven.apache.org/maven-v4_0_0.xsd">
   
   <modelVersion>4.0.0</modelVersion>
   <groupId>com.tutorialspoint.test</groupId>
   <artifactId>helloworld</artifactId>
   <packaging>war</packaging>
   <version>1.0-SNAPSHOT</version>
   <name>helloworld Maven Webapp</name>
   <url>http://maven.apache.org</url >
   
   <dependencies>
      <dependency>
         <groupId>junit</groupId>
         <artifactId>junit</artifactId>
         <version>3.8.1</version>
         <scope>test</scope>
      </dependency>
      
      <dependency>
         <groupId>com.sun.faces</groupId>
         <artifactId>jsf-api</artifactId>
         <version>2.1.7</version>
      </dependency>
      
      <dependency>
         <groupId>com.sun.faces</groupId>
         <artifactId>jsf-impl</artifactId>
         <version>2.1.7</version>
      </dependency>
      
      <dependency>
         <groupId>javax.servlet</groupId>
         <artifactId>jstl</artifactId>
         <version>1.2</version>
      </dependency>
      
      <dependency>
        <groupId>postgresql</groupId>
        <artifactId>postgresql</artifactId>
        <version>9.1-901.jdbc4</version>
     </dependency>
   </dependencies>
   
   <build>
      <finalName>helloworld</finalName>
      <plugins>
         <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-compiler-plugin</artifactId>
            <version>2.3.1</version>
            <configuration>
               <source>1.6</source>
               <target>1.6</target>
            </configuration>
         </plugin>
         
         <plugin>
            <artifactId>maven-resources-plugin</artifactId>
            <version>2.6</version>
            <executions>
               <execution>
                  <id>copy-resources</id>
                  <phase>validate</phase>
                  <goals>
                     <goal>copy-resources</goal>
                  </goals>
                  
                  <configuration>
                     <outputDirectory>${basedir}/target/helloworld/resources
                        </outputDirectory>
                     <resources>          
                        <resource>
                           <directory>src/main/resources</directory>
                           <filtering>true</filtering>
                        </resource>
                     </resources>              
                  </configuration>            
               </execution>
            </executions>
         </plugin>
      
      </plugins>
   </build>
</project>

Author.java

package com.tutorialspoint.test;

public class Author {
   int id;
   String name;
   
   public String getName() {
      return name;
   }
   
   public void setName(String name) {
      this.name = name;
   }
   
   public int getId() {
      return id;
   }
   
   public void setId(int id) {
      this.id = id;
   }
}

UserData.java

package com.tutorialspoint.test;

import java.io.Serializable;

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;

import java.util.ArrayList;
import java.util.List;

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

@ManagedBean(name = "userData", eager = true)
@SessionScoped
public class UserData implements Serializable {
   private static final long serialVersionUID = 1L;

   public List<Author> getAuthors() {
      ResultSet rs = null;
      PreparedStatement pst = null;
      Connection con = getConnection();
      String stm = "Select * from authors";
      List<Author> records = new ArrayList<Author>();
      
      try {   
         pst = con.prepareStatement(stm);
         pst.execute();
         rs = pst.getResultSet();

         while(rs.next()) {
            Author author = new Author();
            author.setId(rs.getInt(1));
            author.setName(rs.getString(2));
            records.add(author);				
         }
      } catch (SQLException e) {
         e.printStackTrace();
      }
      return records;
   }

   public Connection getConnection() {
      Connection con = null;
      String url = "jdbc:postgresql://127.0.0.1/testdb";
      String user = "user1";
      String password = "user1";
      
      try {
         con = DriverManager.getConnection(url, user, password);
         System.out.println("Connection completed.");
      } catch (SQLException ex) {
         System.out.println(ex.getMessage());
      }
      
      finally {
      }
      return con;
   }
}

home.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:head>
      <title>JSF Tutorial!</title>
      <h:outputStylesheet library = "css" name = "styles.css"  /> 
   </h:head>
   
   <h:body>
      <h2>JDBC Integration Example</h2>
      
      <h:dataTable value = "#{userData.authors}" var = "c"
         styleClass = "authorTable"
         headerClass = "authorTableHeader"
         rowClasses = "authorTableOddRow,authorTableEvenRow">
         
         <h:column><f:facet name = "header">Author ID</f:facet>
            #{c.id}
         </h:column>
         
         <h:column><f:facet name = "header">Name</f:facet>
            #{c.name}
         </h:column>
      </h:dataTable>
   </h:body>
</html> 

完成所有更改后,让我们像在 JSF - 第一个应用程序章节中一样编译并运行应用程序。如果您的应用程序一切正常,这将产生以下结果。

JSF JDBC Result

JSF - Spring 集成

Spring 提供了一个特殊的类 DelegatingVariableResolver,可以无缝地将 JSF 和 Spring 集成在一起。

在 JSF 中集成 Spring 依赖注入 (IOC) 功能需要执行以下步骤。

步骤 1:添加 DelegatingVariableResolver

在 faces-config.xml 中添加一个 variable-resolver 条目,指向 Spring 类 DelegatingVariableResolver

<faces-config>
   <application>
   <variable-resolver>
      org.springframework.web.jsf.DelegatingVariableResolver
   </variable-resolver>
   ...
</faces-config>

步骤 2:添加上下文监听器

在 web.xml 中添加 Spring 框架提供的 ContextLoaderListenerRequestContextListener 监听器。

<web-app>
   ...
   <!-- Add Support for Spring -->
   <listener>
      <listener-class>
         org.springframework.web.context.ContextLoaderListener
      </listener-class>
   </listener>
   
   <listener>
      <listener-class>
         org.springframework.web.context.request.RequestContextListener
      </listener-class>
   </listener>
   ...
</web-app>

步骤 3:定义依赖项

在 applicationContext.xml 中定义将在托管 Bean 中用作依赖项的 Bean。

<beans>
   <bean id = "messageService" 
      class = "com.tutorialspoint.test.MessageServiceImpl">
      <property name = "message" value = "Hello World!" />        
   </bean>
</beans>

步骤 4:添加依赖项

DelegatingVariableResolver 首先将值查找委托给 JSF 的默认解析器,然后委托给 Spring 的 WebApplicationContext。这允许轻松地将基于 Spring 的依赖项注入到 JSF 托管 Bean 中。

我们在这里将 messageService 注入为基于 Spring 的依赖项。

<faces-config>
   ...
   <managed-bean>
      <managed-bean-name>userData</managed-bean-name>
      <managed-bean-class>com.tutorialspoint.test.UserData</managed-bean-class>
      <managed-bean-scope>request</managed-bean-scope>
      
      <managed-property>
         <property-name>messageService</property-name>
         <value>#{messageService}</value>
      </managed-property>
   </managed-bean> 
</faces-config>

步骤 5:使用依赖项

//jsf managed bean
public class UserData {
   
   //spring managed dependency
   private MessageService messageService;

   public void setMessageService(MessageService messageService) {
      this.messageService = messageService;
   }

   public String getGreetingMessage() {
      return messageService.getGreetingMessage();
   }
}

示例应用程序

让我们创建一个测试 JSF 应用程序来测试 Spring 集成。

步骤 描述
1 JSF - 第一个应用程序章节中说明的基础上,创建一个名为helloworld的项目,放在package com.tutorialspoint.test下。
2 修改 pom.xml 文件,如下所述。
3 WEB-INF 文件夹下创建 faces-config.xml 文件,如下所述。
4 修改 web.xml 文件,如下所述。
5 WEB-INF 文件夹下创建 applicationContext.xml 文件,如下所述。
6 com.tutorialspoint.test 包下创建 MessageService.java 文件,如下所述。
7 com.tutorialspoint.test 包下创建 MessageServiceImpl.java 文件,如下所述。
8 com.tutorialspoint.test 包下创建 UserData.java 文件,如下所述。
9 修改home.xhtml,如下所示。保持其余文件不变。
10 编译并运行应用程序以确保业务逻辑按要求工作。
11 最后,以 war 文件的形式构建应用程序,并将其部署到 Apache Tomcat Webserver 中。
12 使用下面最后一步中说明的适当 URL 启动您的 Web 应用程序。

pom.xml

<project xmlns = "http://maven.apache.org/POM/4.0.0" 
   xmlns:xsi = "http://www.w3.org/2001/XMLSchema-instance"
   xsi:schemaLocation = "http://maven.apache.org/POM/4.0.0
   http://maven.apache.org/maven-v4_0_0.xsd">
   
   <modelVersion>4.0.0</modelVersion>
   <groupId>com.tutorialspoint.test</groupId>
   <artifactId>helloworld</artifactId>
   <packaging>war</packaging>
   <version>1.0-SNAPSHOT</version>
   <name>helloworld Maven Webapp</name>
   <url>http://maven.apache.org</url>
   
   <dependencies>
      <dependency>
         <groupId>junit</groupId>
         <artifactId>junit</artifactId>
         <version>3.8.1</version>
         <scope>test</scope>
      </dependency>
      
      <dependency>
         <groupId>com.sun.faces</groupId>
         <artifactId>jsf-api</artifactId>
         <version>2.1.7</version>
      </dependency>
      
      <dependency>
         <groupId>com.sun.faces</groupId>
         <artifactId>jsf-impl</artifactId>
         <version>2.1.7</version>
      </dependency>
      
      <dependency>
         <groupId>javax.servlet</groupId>
         <artifactId>jstl</artifactId>
         <version>1.2</version>
      </dependency>
      
      <dependency>
         <groupId>org.springframework</groupId>
         <artifactId>spring-core</artifactId>
         <version>3.1.2.RELEASE</version>
      </dependency>
      
      <dependency>
         <groupId>org.springframework</groupId>
         <artifactId>spring-web</artifactId>
         <version>3.1.2.RELEASE</version> 
      </dependency>
   </dependencies>
   
   <build>
      <finalName>helloworld</finalName>
      <plugins>
         <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-compiler-plugin</artifactId>
            <version>2.3.1</version>
            <configuration>
               <source>1.6</source>
               <target>1.6</target>
            </configuration>
         </plugin>
         
         <plugin>
            <artifactId>maven-resources-plugin</artifactId>
            <version>2.6</version>
            
            <executions>
               <execution>
                  <id>copy-resources</id>
                  <phase>validate</phase>
                  <goals>
                     <goal>copy-resources</goal>
                  </goals>
                  
                  <configuration>
                     <outputDirectory>${basedir}/target/helloworld/resources
                        </outputDirectory>
                     <resources>          
                        <resource>
                           <directory>src/main/resources</directory>
                           <filtering>true</filtering>
                        </resource>
                     </resources>              
                  </configuration>            
               </execution>
            </executions>
         
         </plugin>
      </plugins>
   </build>
</project>

faces-config.xml

<?xml version = "1.0" encoding = "UTF-8"?>
<faces-config
   xmlns = "http://java.sun.com/xml/ns/javaee"
   xmlns:xsi = "http://www.w3.org/2001/XMLSchema-instance"
   xsi:schemaLocation = "http://java.sun.com/xml/ns/javaee 
   http://java.sun.com/xml/ns/javaee/web-facesconfig_2_0.xsd"
   version = "2.0"> 
   
   <application>
      <variable-resolver>
         org.springframework.web.jsf.DelegatingVariableResolver
      </variable-resolver>
   </application>
   
   <managed-bean>
      <managed-bean-name>userData</managed-bean-name>
      <managed-bean-class>com.tutorialspoint.test.UserData</managed-bean-class>
      <managed-bean-scope>request</managed-bean-scope>
      <managed-property>
         <property-name>messageService</property-name>
         <value>#{messageService}</value>
      </managed-property>
   </managed-bean> 
</faces-config>

web.xml

<!DOCTYPE web-app PUBLIC
   "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN"
   "http://java.sun.com/dtd/web-app_2_3.dtd" >

<web-app>
   <display-name>Archetype Created Web Application</display-name>

   <context-param>
      <param-name>javax.faces.PROJECT_STAGE</param-name>
      <param-value>Development</param-value>
   </context-param>	
   
   <!-- Add Support for Spring -->
   <listener> 
      <listener-class>
         org.springframework.web.context.ContextLoaderListener
      </listener-class>
   </listener>
   
   <listener>
      <listener-class>
         org.springframework.web.context.request.RequestContextListener
      </listener-class>
   </listener>
   
   <servlet>
      <servlet-name>Faces Servlet</servlet-name>
      <servlet-class>javax.faces.webapp.FacesServlet</servlet-class>
   </servlet>
   
   <servlet-mapping>
      <servlet-name>Faces Servlet</servlet-name>
      <url-pattern>*.jsf</url-pattern>
   </servlet-mapping>
</web-app>

applicationContext.xml

<?xml version = "1.0" encoding = "UTF-8"?>
<!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN 2.0//EN" 
   "http://www.springframework.org/dtd/spring-beans-2.0.dtd">

<beans>
   <bean id = "messageService" 
      class = "com.tutorialspoint.test.MessageServiceImpl">
      <property name = "message" value = "Hello World!" />        
   </bean>
</beans>

MessageService.java

package com.tutorialspoint.test;

public interface MessageService {
   String getGreetingMessage();
}

MessageServiceImpl.java

package com.tutorialspoint.test;

public class MessageServiceImpl implements MessageService {
   private String message;
   
   public String getGreetingMessage() {
      return message;
   }
   
   public String getMessage() {
      return message;
   }
   public void setMessage(String message) {
      this.message = message;
   }
}

UserData.java

package com.tutorialspoint.test;

import java.io.Serializable;

public class UserData implements Serializable {

   private static final long serialVersionUID = 1L;
	private MessageService messageService;

   public MessageService getMessageService() {
      return messageService;
   }

   public void setMessageService(MessageService messageService) {
      this.messageService = messageService;
   }

   public String getGreetingMessage() {
      return messageService.getGreetingMessage();
   }
}

home.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:head>
      <title>JSF Tutorial!</title>
   </h:head>
   
   <h:body>
      <h2>Spring Integration Example</h2>
      #{userData.greetingMessage}
   </h:body>
</html> 

完成所有更改后,让我们像在 JSF - 第一个应用程序章节中一样编译并运行应用程序。如果您的应用程序一切正常,这将产生以下结果。

JSF Spring Result

JSF - 表达式语言

JSF 提供了一个丰富的表达式语言。我们可以使用 #{operation-expression} 表示法编写常规操作。以下是 JSF 表达式语言的一些优点。

  • 可以引用 Bean 属性,其中 Bean 可以是存储在请求、会话或应用程序作用域中的对象,或者是一个托管 Bean。

  • 提供对集合元素的轻松访问,集合可以是列表、映射或数组。

  • 提供对预定义对象的轻松访问,例如请求。

  • 可以使用表达式语言执行算术、逻辑和关系运算。

  • 自动类型转换。

  • 将缺失值显示为空字符串,而不是 NullPointerException。

示例应用程序

让我们创建一个测试 JSF 应用程序来测试表达式语言。

步骤 描述
1 JSF - 第一个应用程序章节中说明的基础上,创建一个名为helloworld的项目,放在package com.tutorialspoint.test下。
2 修改 com.tutorialspoint.test 包下的 UserData.java 文件,如下所述。
3 修改home.xhtml,如下所示。保持其余文件不变。
4 编译并运行应用程序以确保业务逻辑按要求工作。
5 最后,以 war 文件的形式构建应用程序,并将其部署到 Apache Tomcat Webserver 中。
6 使用下面最后一步中说明的适当 URL 启动您的 Web 应用程序。

UserData.java

package com.tutorialspoint.test;

import java.io.Serializable;
import java.util.Date;

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

@ManagedBean(name = "userData", eager = true)
@SessionScoped
public class UserData implements Serializable {
   private static final long serialVersionUID = 1L;
   private Date createTime = new Date();
   private String message = "Hello World!";

   public Date getCreateTime() {
      return(createTime);
   }
   
   public String getMessage() {
      return(message);
   }
}

home.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:head>
      <title>JSF Tutorial!</title>
   </h:head>
   
   <h:body>
      <h2>Expression Language Example</h2>
      Creation time: 
      <h:outputText value = "#{userData.createTime}"/>
      <br/><br/>
      Message: 
      <h:outputText value = "#{userData.message}"/>
   </h:body>
</html> 

完成所有更改后,让我们像在 JSF - 第一个应用程序章节中一样编译并运行应用程序。如果您的应用程序一切正常,这将产生以下结果。

JSF Expression Language Result

JSF - 国际化

国际化是一种技术,其中状态消息、GUI 组件标签、货币、日期不会硬编码在程序中。相反,它们存储在源代码外部的资源包中,并动态检索。JSF 提供了一种非常方便的方法来处理资源包。

国际化 JSF 应用程序需要执行以下步骤。

步骤 1:定义属性文件

为每个区域设置创建属性文件。名称应采用 <file-name>_<locale>.properties 格式。

默认区域设置可以在文件名中省略。

messages.properties

greeting = Hello World!

messages_fr.properties

greeting = Bonjour tout le monde!

步骤 2:更新 faces-config.xml

faces-config.xml

<application>
   <locale-config>
      <default-locale>en</default-locale>
      <supported-locale>fr</supported-locale>
   </locale-config>
   
   <resource-bundle>
      <base-name>com.tutorialspoint.messages</base-name>
      <var>msg</var>
   </resource-bundle>
</application>

步骤 3:使用资源包变量

home.xhtml

<h:outputText value = "#{msg['greeting']}" />

示例应用程序

让我们创建一个测试 JSF 应用程序来测试 JSF 中的国际化。

步骤 描述
1 JSF - 第一个应用程序章节中说明的基础上,创建一个名为helloworld的项目,放在package com.tutorialspoint.test下。
2 src → mai 文件夹下创建 resources 文件夹。
3 src → main → resources 文件夹下创建 com 文件夹。
4 src → main → resources → com 文件夹下创建 tutorialspoint 文件夹。
5 src → main → resources → com → tutorialspoint 文件夹下创建 messages.properties 文件。修改它,如下所述。
6 src → main → resources → com → tutorialspoint 文件夹下创建 messages_fr.properties 文件。修改它,如下所述。
7 WEB-INFf 文件夹下创建 faces-config.xml 文件,如下所述。
8 com.tutorialspoint.test 包下创建 UserData.java 文件,如下所述。
9 修改home.xhtml,如下所示。保持其余文件不变。
10 编译并运行应用程序以确保业务逻辑按要求工作。
11 最后,以 war 文件的形式构建应用程序,并将其部署到 Apache Tomcat Webserver 中。
12 使用下面最后一步中说明的适当 URL 启动您的 Web 应用程序。

messages.properties

greeting = Hello World!

messages_fr.properties

greeting = Bonjour tout le monde!

faces-config.xml

<?xml version = "1.0" encoding = "UTF-8"?>
<faces-config
   xmlns = "http://java.sun.com/xml/ns/javaee"
   xmlns:xsi = "http://www.w3.org/2001/XMLSchema-instance"
   xsi:schemaLocation = "http://java.sun.com/xml/ns/javaee 
   http://java.sun.com/xml/ns/javaee/web-facesconfig_2_0.xsd"
   version = "2.0">
   
   <application>
      <locale-config>
         <default-locale>en</default-locale>
         <supported-locale>fr</supported-locale>
      </locale-config>
      
      <resource-bundle>
         <base-name>com.tutorialspoint.messages</base-name>
         <var>msg</var>
      </resource-bundle>
   </application>
</faces-config>

UserData.java

package com.tutorialspoint.test;

import java.io.Serializable;
import java.util.LinkedHashMap;
import java.util.Locale;
import java.util.Map;

import javax.faces.bean.ManagedBean;
import javax.faces.bean.SessionScoped;
import javax.faces.context.FacesContext;
import javax.faces.event.ValueChangeEvent;

@ManagedBean(name = "userData", eager = true)
@SessionScoped
public class UserData implements Serializable {
   private static final long serialVersionUID = 1L;
   private String locale;

   private static Map<String,Object> countries;
      static {
      
      countries = new LinkedHashMap<String,Object>();
      countries.put("English", Locale.ENGLISH);
      countries.put("French", Locale.FRENCH);
   }

   public Map<String, Object> getCountries() {
      return countries;
   }

   public String getLocale() {
      return locale;
   }

   public void setLocale(String locale) {
      this.locale = locale;
   }

   //value change event listener
   public void localeChanged(ValueChangeEvent e) {
      String newLocaleValue = e.getNewValue().toString();
      
      for (Map.Entry<String, Object> entry : countries.entrySet()) {
         
         if(entry.getValue().toString().equals(newLocaleValue)) {
            FacesContext.getCurrentInstance()
               .getViewRoot().setLocale((Locale)entry.getValue());         
         }
      }
   }
}

home.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:h = "http://java.sun.com/jsf/html"
xmlns:f = "http://java.sun.com/jsf/core">
   
   <h:head>
      <title>JSF tutorial</title>	 	
   </h:head>
   
   <h:body> 
      <h2>Internalization Language Example</h2>
      
      <h:form>
         <h3><h:outputText value = "#{msg['greeting']}" /></h3>
         
         <h:panelGrid columns = "2"> 
            Language : 
            <h:selectOneMenu value = "#{userData.locale}" onchange = "submit()"
               valueChangeListener = "#{userData.localeChanged}">
               <f:selectItems value = "#{userData.countries}" /> 
            </h:selectOneMenu> 
         </h:panelGrid> 
      
      </h:form>
   </h:body>
</html>

完成所有更改后,让我们像在 JSF - 第一个应用程序章节中一样编译并运行应用程序。如果您的应用程序一切正常,这将产生以下结果。

JSF Internationalization Result

从下拉列表中更改语言。您将看到以下输出。

JSF Internationalization Result1
广告