JSF - 快速指南
JSF - Overview
什么是JSF?
JavaServer Faces (JSF)是一个MVC Web框架,它简化了使用页面中可重用UI组件的基于服务器的应用程序的用户界面(UI)的构造。 JSF提供了一个连接UI小部件与数据源和服务器端事件处理程序的工具。 JSF规范定义了一组标准UI组件,并提供了用于开发组件的应用程序编程接口(API)。 JSF支持重用和扩展现有的标准UI组件。
好处 (Benefits)
JSF减少了创建和维护应用程序的工作量,这些应用程序将在Java应用程序服务器上运行,并将应用程序UI呈现给目标客户端。 JSF促进Web应用程序开发 -
- 提供可重用的UI组件
- 在UI组件之间轻松传输数据
- 跨多个服务器请求管理UI状态
- 启用自定义组件的实现
- 将客户端事件连接到服务器端应用程序代码
JSF UI组件模型
JSF为开发人员提供了从UI组件集合创建Web应用程序的功能,这些UI组件可以以不同的方式为多种客户端类型(例如 - HTML浏览器,无线或WAP设备)呈现自己。
JSF提供 -
核心库
一组基本UI组件 - 标准HTML输入元素
扩展基本UI组件以创建其他UI组件库或扩展现有组件
多种呈现功能,使JSF UI组件能够根据客户端类型呈现不同的呈现方式
JSF - Environment Setup
本章将指导您如何准备开发环境以开始使用JSF Framework。 在设置JSF Framework之前,您将学习如何在计算机上设置JDK,Eclipse,Maven和Tomcat。
系统需求 (System Requirement)
JSF需要JDK 1.5或更高版本,因此第一个要求是在您的计算机上安装JDK。
JDK | 1.5或以上 |
Memory | 没有最低要求 |
Disk Space | 没有最低要求 |
Operating System | 没有最低要求 |
JSF应用程序开发的环境设置
按照给定的步骤设置环境以开始JSF应用程序开发。
步骤1:验证计算机上的Java安装
打开控制台并执行以下Java命令。
OS | 任务 | 命令 |
---|---|---|
Windows | 打开命令控制台 | c:\> java -version |
Linux | 打开命令终端 | $ java -version |
Mac | 开放式终端 | 机器:~joseph $ java -version |
让我们验证所有操作系统的输出 -
OS | 生成输出 |
---|---|
Windows | java版“1.6.0_21” Java(TM)SE运行时环境(版本1.6.0_21-b07) Java HotSpot(TM)客户端VM(版本17.0-b17,混合模式,共享) |
Linux | java版“1.6.0_21” Java(TM)SE运行时环境(版本1.6.0_21-b07) Java HotSpot(TM)客户端VM(版本17.0-b17,混合模式,共享) |
Mac | java版“1.6.0_21” Java(TM)SE运行时环境(版本1.6.0_21-b07) Java HotSpot(TM)64位服务器VM(内置17.0-b17,混合模式,共享) |
第2步:设置Java开发工具包(JDK)
如果您没有安装Java,那么您可以从Oracle的Java站点 - Java SE下载安装Java软件开发工具包(SDK)。 您将找到有关在下载文件中安装JDK的说明,请按照给出的说明安装和配置设置。 最后,设置PATH和JAVA_HOME环境变量以引用包含java和javac的目录,通常分别是java_install_dir/bin和java_install_dir。
将JAVA_HOME环境变量设置为指向计算机上安装Java的基本目录位置。
例如 -
OS | output |
---|---|
Windows | 将环境变量JAVA_HOME设置为C:\Program Files\Java\jdk1.6.0_21 |
Linux | 导出JAVA_HOME =/usr/local/java-current |
Mac | 导出JAVA_HOME =/Library/Java/Home |
将Java编译器位置附加到系统路径。
OS | output |
---|---|
Windows | 将字符串;%JAVA_HOME%\ bin附加到系统变量Path的末尾。 |
Linux | 导出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
成功启动后,如果一切正常,则会显示以下结果。
*Note - 使用以下eclipse软件更新站点将m2eclipse插件安装到eclipse
m2eclipse插件 - https://m2eclipse.sonatype.org/update/ 。
这个插件使开发人员能够在eclipse中使用嵌入式/外部maven安装来运行maven命令。
第4步:下载Maven存档
从https://maven.apache.org/download.html下载Maven 2.2.1
OS | 存档名称 |
---|---|
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。
OS | 位置(根据您的安装可能会有所不同) |
---|---|
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添加到环境变量中。
OS | output |
---|---|
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变量附加到系统路径。
OS | output |
---|---|
Windows | 将字符串;%M2%附加到系统变量Path的末尾。 |
Linux | export PATH = $ M2:$ PATH |
Mac | export PATH = $ M2:$ PATH |
第8步:验证Maven安装。
打开控制台,执行以下mvn命令。
OS | 任务 | 命令 |
---|---|---|
Windows | 打开命令控制台 | c:\> mvn --version |
Linux | 打开命令终端 | $ mvn --version |
Mac | 开放式终端 | machine:~ wiki$ mvn --version |
最后,验证上述命令的输出,如下表所示。
OS | output |
---|---|
Windows | Apache Maven 2.2.1(r801777; 2009-08-07 00:46:01 + 0530) Java版本: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版本: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版本:1.6.0_21 Java home:C:\Program Files\Java\jdk1.6.0_21\jre |
第9步:设置Apache Tomcat
您可以从https://tomcat.apache.org/下载最新版本的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
成功启动后,Tomcat附带的默认Web应用程序将通过访问http://localhost:8080/ 。 如果一切正常,那么它将显示以下结果。
有关配置和运行Tomcat的更多信息,请参阅此处包含的文档以及Tomcat网站 - http://tomcat.apache.org
可以通过在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 - Architecture
JSF技术是用于开发,构建服务器端用户界面组件并在Web应用程序中使用它们的框架。 JSF技术基于模型视图控制器(MVC)架构,用于将逻辑与表示分离。
什么是MVC设计模式?
MVC设计模式使用三个独立模块设计应用程序 -
S.No | 模块和描述 |
---|---|
1 | Model 携带数据并登录 |
2 | View 显示用户界面 |
3 | Controller 处理应用程序的处理。 |
MVC设计模式的目的是将模型和表示分开,使开发人员能够专注于他们的核心技能并更清晰地进行协作。
Web设计人员必须只关注视图层而不是模型和控制器层。 开发人员可以更改模型的代码,通常无需更改视图层。 控制器用于处理用户操作。 在此过程中,可以更改图层模型和视图。
JSF架构
JSF应用程序类似于任何其他基于Java技术的Web应用程序; 它在Java servlet容器中运行,并包含 -
JavaBeans组件作为包含特定于应用程序的功能和数据的模型
用于表示事件处理程序和验证程序的自定义标记库
用于呈现UI组件的自定义标记库
UI组件在服务器上表示为有状态对象
服务器端帮助程序类
验证器,事件处理程序和导航处理程序
应用配置资源文件,用于配置应用资源
有些控制器可用于执行用户操作。 UI可以由网页作者创建,业务逻辑可以由托管bean使用。
JSF提供了几种渲染单个组件的机制。 网页设计者可以选择所需的表示,应用程序开发人员不需要知道使用哪种机制来呈现JSF UI组件。
JSF - Life Cycle
JSF应用程序生命周期包括六个阶段,如下所示 -
- Restore view phase
- 应用请求值阶段; 过程事件
- 流程验证阶段; 过程事件
- 更新模型值阶段; 过程事件
- 调用应用阶段; 过程事件
- 渲染响应阶段
这六个阶段显示了JSF处理表单的顺序。 该列表显示了每个阶段的事件处理可能执行顺序的阶段。
阶段1:还原视图
只要单击链接或按钮并且JSF收到请求,JSF就会开始恢复视图阶段。
在此阶段,JSF构建视图,将事件处理程序和验证程序连接到UI组件,并将视图保存在FacesContext实例中。 FacesContext实例现在将包含处理请求所需的所有信息。
阶段2:应用请求值
在创建/恢复组件树之后,组件树中的每个组件都使用decode方法从请求参数中提取其新值。 Component存储此值。 如果转换失败,则会生成错误消息并在FacesContext上排队。 此消息将在呈现响应阶段显示,并显示任何验证错误。
如果任何解码方法事件侦听器在当前FacesContext实例上调用renderResponse,则JSF将移至渲染响应阶段。
阶段3:流程验证
在此阶段,JSF处理在组件树上注册的所有验证器。 它检查验证的组件属性规则,并将这些规则与为组件存储的本地值进行比较。
如果本地值无效,JSF会向FacesContext实例添加一条错误消息,生命周期将前进到呈现响应阶段,并再次显示相同的页面并显示错误消息。
阶段4:更新模型值
在JSF检查数据是否有效之后,它会遍历组件树并将相应的服务器端对象属性设置为组件的本地值。 JSF将更新与输入组件的value属性对应的bean属性。
如果任何updateModels方法在当前FacesContext实例上调用renderResponse,则JSF将移至渲染响应阶段。
阶段5:调用应用程序
在此阶段,JSF处理任何应用程序级事件,例如提交表单/链接到另一个页面。
阶段6:渲染响应
在此阶段,如果应用程序使用JSP页面,JSF会要求容器/应用程序服务器呈现页面。 对于初始请求,当JSP容器执行页面时,页面上表示的组件将添加到组件树中。 如果这不是初始请求,则已构建组件树,因此无需再次添加组件。 在任何一种情况下,组件都将自身呈现为JSP容器/应用程序服务器遍历页面中的标记。
在呈现视图的内容之后,将保存响应状态,以便后续请求可以访问它,并且它可用于还原视图阶段。
JSF - First Application
要创建一个简单的JSF应用程序,我们将使用maven-archetype-webapp插件。 在下面的示例中,我们将在C:\JSF文件夹中创建基于maven的Web应用程序项目。
创建项目
让我们打开命令控制台,转到C:\ 》 JSF目录并执行以下mvn命令。
C:\JSF>mvn archetype:create
-DgroupId = com.iowiki.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.iowiki.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.iowiki.test
[INFO] Parameter: packageName, Value: com.iowiki.test
[INFO] Parameter: package, Value: com.iowiki.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目录。 您将看到一个名为helloworld的Java Web应用程序项目(在artifactId中指定)。 Maven使用标准目录布局,如以下屏幕截图所示。
使用上面的示例,我们可以理解以下关键概念。
S.No | 文件夹结构和描述 |
---|---|
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>
Complete 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.iowiki.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中导入项目。
转到File → Import... → Existing project into workspace 。
选择helloworld的根目录。
Copy projects into workspace到要检查的Copy projects into workspace中。
单击完成按钮。
Eclipse将在其工作区C:\ → Projects → Data → WorkSpace导入和复制项目。
在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 as com → iowiki → test下创建一个包结构, src → main → java as com → iowiki → test 。 在此包中创建HelloWorld.java类。 更新HelloWorld.java的代码,如下所示。
package com.iowiki.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>
构建项目 (Build the Project)
以下是步骤。
在eclipse中选择helloworld项目
使用运行方式向导
选择Run As → Maven package
Maven将开始构建项目,并将在C:\ → Projects → Data → WorkSpace → helloworld → target文件夹下创建helloworld.war。
[INFO] Scanning for projects...
[INFO] -----------------------------------------------------
[INFO] Building helloworld Maven Webapp
[INFO]
[INFO] Id: com.iowiki.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 installation directory → webapps folder 。
启动tomcat服务器。
查看webapps目录,应该创建一个helloworld文件夹。
现在helloworld.war已成功部署在Tomcat Webserver根目录中。
运行应用程序
在Web浏览器中输入URL: http://localhost:8080/helloworld/home.jsf以启动应用程序。
服务器名称(localhost)和端口(8080)可能因tomcat配置而异。
JSF - Managed Beans
Managed Bean是在JSF中注册的常规Java Bean类。 换句话说,Managed Beans是由JSF框架管理的Java bean。 托管bean包含getter和setter方法,业务逻辑,甚至是一个支持bean(bean包含所有HTML表单值)。
托管bean用作UI组件的Model。 可以从JSF页面访问Managed 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.iowiki.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.iowiki.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将默认为请求范围。 下表简要讨论了每个范围。
S.No | 范围和描述 |
---|---|
1 | @RequestScoped 只要HTTP请求 - 响应存在,Bean就会存在。 它在HTTP请求时创建,并在与HTTP请求关联的HTTP响应完成时被销毁。 |
2 | @NoneScoped 只要进行一次EL评估,Bean就会存在。 它是在EL评估时创建的,并在EL评估后立即销毁。 |
3 | @ViewScoped 只要用户在浏览器窗口/选项卡中与相同的JSF视图进行交互,Bean就会存在。 它是在HTTP请求时创建的,一旦用户回发到另一个视图就会被销毁。 |
4 | @SessionScoped 只要HTTP会话存在,Bean就会存在。 它在会话中涉及此bean的第一个HTTP请求时创建,并在HTTP会话失效时被销毁。 |
5 | @ApplicationScoped 只要Web应用程序存在,Bean就会存在。 它是在应用程序中涉及此bean的第一个HTTP请求时创建的(或者当Web应用程序启动并且@ManagedBean中设置了eager = true属性时),并在Web应用程序关闭时被销毁。 |
6 | @CustomScoped Bean只要在自定义Map中的bean条目生效,该自定义Map就是为此范围创建的。 |
@ManagedProperty Annotation
JSF是一个简单的静态依赖注入(DI)框架。 使用@ManagedProperty批注,可以将托管bean的属性注入另一个托管bean。
示例应用
让我们创建一个测试JSF应用程序来测试托管bean的上述注释。
步 | 描述 |
---|---|
1 | 在com.iowiki.test包下创建一个名为helloworld的项目,如JSF - Create Application一章中所述。 |
2 | 修改HelloWorld.java ,如下所述。 保持其余文件不变。 |
3 | 在com.iowiki.test包下创建Message.java ,如下所述。 |
4 | 编译并运行应用程序以确保业务逻辑按照要求运行。 |
5 | 最后,以war文件的形式构建应用程序并将其部署在Apache Tomcat Webserver中。 |
6 | 使用适当的URL启动Web应用程序,如下面的最后一步所述。 |
HelloWorld.java
package com.iowiki.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.iowiki.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 - Page Navigation
导航规则是JSF Framework提供的那些规则,用于描述单击按钮或链接时要显示的视图。
可以在名为faces-config.xml的JSF配置文件中定义导航规则。 它们可以在托管bean中定义。
导航规则可以包含可以显示结果视图的条件。 JSF 2.0也提供隐式导航,其中不需要定义导航规则。
隐式导航
JSF 2.0提供了名为implicit navigation auto view page resolver机制。 在这种情况下,您只需要将视图名称放在action属性中,JSF将在已部署的应用程序中自动搜索正确的view页面。
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 。
托管Bean中的自动导航
在托管bean中定义一个方法以返回视图名称。
@ManagedBean(name = "navigationController", eager = true)
@RequestScoped
public class NavigationController implements Serializable {
public String moveToPage1() {
return "page1";
}
}
使用托管bean获取任何JSF UI Component的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 。
条件导航
使用托管bean,我们可以非常轻松地控制导航。 查看托管bean中的以下代码。
@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";
}
}
}
将pageId作为JSF UI Component中的请求参数传递。
<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将此参数传递给navigationController的托管属性pageId
现在调用navigationController.showPage(),它将在检查pageId后将视图返回到page1
JSF将视图名称page1解析为page1.xhtml扩展名
在当前目录中找到相应的视图文件page1.xhtml
基于from-action解决导航问题
即使托管bean不同的方法返回相同的视图名称,JSF也提供导航解析选项。
查看托管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() ,它将视图作为页面返回
JSF将解析视图名称page1因为视图名称是page and from-action faces-config is navigationController.processPage1 page and from-action faces-config is navigationController.processPage1
在当前目录中找到相应的视图文件page1.xhtml
转发与重定向
默认情况下,JSF在导航到另一个页面时执行服务器页面,并且应用程序的URL不会更改。
要启用页面重定向,请在视图名称的末尾追加faces-redirect=true 。
<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>
这里,当单击Forward下的Page1按钮时,您将得到以下结果。
在单击Redirect下的Page1按钮时,您将获得以下结果。
示例应用
让我们创建一个测试JSF应用程序来测试所有上面的导航示例。
步 | 描述 |
---|---|
1 | 在package com.iowiki.test下创建一个名为helloworld的项目,如JSF - Create Application一章中所述。 |
2 | 在com.iowiki.test包下创建NavigationController.java ,如下所述。 |
3 | 在WEB-INF文件夹下创建faces-config.xml并更新其内容,如下所述。 |
4 | 更新WEB-INF文件夹下的web.xml ,如下所述。 |
5 | 创建page1.xhtml和page2.xhtml并在webapp文件夹下修改home.xhtml ,如下所述。 |
6 | 编译并运行应用程序以确保业务逻辑按照要求运行。 |
7 | 最后,以war文件的形式构建应用程序并将其部署在Apache Tomcat Webserver中。 |
8 | 使用适当的URL启动Web应用程序,如下面的最后一步所述。 |
NavigationController.java
package com.iowiki.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 - Basic Tags
在本章中,您将了解各种类型的基本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中重要的基本标记。
S.No | 标签和说明 |
---|---|
1 | h:inputText 呈现类型=“text”,文本框的HTML输入。 |
2 | h:inputSecret 呈现type =“password”,文本框的HTML输入。 |
3 | h:inputTextarea 呈现HTML textarea字段。 |
4 | h:inputHidden 呈现type =“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 呈现类型=“提交”按钮的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 Component。 |
24 | f:attribute 将属性传递给JSF UI组件。 |
25 | f:setPropertyActionListener 设置托管bean的属性值。 |
JSF - Facelets Tags
JSF提供了特殊标记,用于为名为facelets标记的Web应用程序创建公共布局。 这些标签提供了在一个地方管理多个页面的公共部分的灵活性。
对于这些标记,您需要在html节点中使用以下URI名称空间。
<html
xmlns = "http://www.w3.org/1999/xhtml"
xmlns:ui = "http://java.sun.com/jsf/facelets"
>
以下是JSF 2.0中重要的Facelets标签。
S.No | 标签和说明 |
---|---|
1 | Templates 我们将演示如何使用以下标记来使用模板
|
2 | Parameters 我们将演示如何使用以下标记将参数传递给模板文件
|
3 | Custom 我们将演示如何创建自定义标记 |
4 | Remove 我们将演示从生成的HTML页面中删除JSF代码的功能 |
JSF - Convertor Tags
JSF提供内置转换器,将其UI组件的数据转换为托管bean中使用的对象,反之亦然。 例如,这些标签可以将文本转换为日期对象,也可以验证输入的格式。
对于这些标记,您需要在html节点中使用以下URI名称空间。
<html
xmlns = "http://www.w3.org/1999/xhtml"
xmlns:f = "http://java.sun.com/jsf/core"
>
以下是JSF 2.0中的重要Convertor Tags -
S.No | 标签和说明 |
---|---|
1 | f:convertNumber 将字符串转换为所需格式的数字 |
2 | f:convertDateTime 将字符串转换为所需格式的日期 |
3 | Custom Convertor 创建自定义转换器 |
JSF - Validator Tags
JSF提供内置验证器来验证其UI组件。 这些标签可以验证字段的长度,输入的类型可以是自定义对象。
对于这些标记,您需要在html节点中使用以下URI名称空间。
<html
xmlns = "http://www.w3.org/1999/xhtml"
xmlns:f = "http://java.sun.com/jsf/core"
>
以下是JSF 2.0中重要的Validator标签 -
S.No | 标签和说明 |
---|---|
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操作 -
S.No | 标签和说明 |
---|---|
1 | 显示DataTable 如何显示dataTable |
2 | 添加数据 如何在dataTable中添加新行 |
3 | 编辑数据 如何编辑dataTable中的行 |
4 | 删除数据 如何删除dataTable中的行 |
5 | 使用DataModel 使用DataModel在dataTable中显示行号 |
JSF - Composite Components
JSF为开发人员提供了强大的功能来定义他们自己的自定义组件,可用于呈现自定义内容。
定义自定义组件
在JSF中定义自定义组件的过程分为两步。
步 | 描述 |
---|---|
1a | 创建资源文件夹。 使用复合命名空间在resources文件夹中创建xhtml文件。 |
1b | 使用复合标签composite:interface, composite:attribute和composite:implementation,来定义复合组件的内容。 在composite:implementation使用cc.attrs来获取使用composite:interface composite:attribute定义的变量。 |
步骤1a:创建自定义组件:loginComponent.xhtml
在resources文件夹中创建一个文件夹iowiki,并在其中创建一个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
下表描述了复合标记的使用。
S.No | 标签和说明 |
---|---|
1 | composite:interface 声明可在复合中使用的可配置值:实现。 |
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> where folder-name is folder in resources directory containing the custom component |
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/iowiki">
步骤2b:使用自定义标记:home.xhtml和Pass Values
<h:form>
<tp:loginComponent
usernameLabel = "Enter User Name: "
usernameValue = "#{userData.name}" />
</h:form>
例子 Example Application
让我们创建一个测试JSF应用程序来测试JSF中的自定义组件。
步 | 描述 |
---|---|
1 | 在com.iowiki.test包下创建一个名为helloworld的项目,如JSF - First Application一章中所述。 |
2 | 在src → main文件夹下创建resources文件夹。 |
3 | 在src → main → resources文件夹下创建iowiki文件夹。 |
4 | 在src → main → resources → iowiki文件夹下创建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.iowiki.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/iowiki">
<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 - First Application章节中那样编译和运行应用程序。 如果您的应用程序一切正常,这将产生以下结果。
JSF - Ajax
AJAX代表异步JavaScript和Xml。
Ajax是一种使用JavaScript的HTTPXMLObject将数据发送到服务器并以异步方式从服务器接收数据的技术。 因此,使用Ajax技术,javascript代码与服务器交换数据,更新网页的部分而无需重新加载整个页面。
JSF为进行ajax调用提供了极好的支持。 它提供了f:ajax标签来处理ajax调用。
JSF标签 (JSF Tag)
<f:ajax execute = "input-component-name" render = "output-component-name" />
标签属性 (Tag Attributes)
S.No | 属性和描述 |
---|---|
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 将调用以处理UI事件的JavaScript回调函数的名称。 |
8 | Render 在Ajax请求之后将更新的组件的以空格分隔的ID列表。 |
例子 Example Application
让我们创建一个测试JSF应用程序来测试JSF中的自定义组件。
步 | 描述 |
---|---|
1 | 在com.iowiki.test包下创建一个名为helloworld的项目,如JSF - First Application一章中所述。 |
2 | 修改UserData.java文件,如下所述。 |
3 | 修改home.xhtml ,如下所述。 保持其余文件不变。 |
4 | 编译并运行应用程序以确保业务逻辑按照要求运行。 |
5 | 最后,以war文件的形式构建应用程序并将其部署在Apache Tomcat Webserver中。 |
6 | 使用适当的URL启动Web应用程序,如下面的最后一步所述。 |
UserData.java
package com.iowiki.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/iowiki">
<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 - First Application章节中那样编译和运行应用程序。 如果您的应用程序一切正常,这将产生以下结果。
输入名称,然后按“显示消息”按钮。 如果没有页面刷新/表单提交,您将看到以下结果。
JSF - Event Handling
当用户单击JSF按钮或链接或更改文本字段中的任何值时,JSF UI组件将触发一个事件,该事件将由应用程序代码处理。 要处理此类事件,应在应用程序代码或托管bean中注册事件处理程序。
当UI组件检查用户事件是否已发生时,它会创建相应事件类的实例并将其添加到事件列表中。 然后,Component触发事件,即检查该事件的侦听器列表,并在每个侦听器或处理程序上调用事件通知方法。
JSF还提供系统级事件处理程序,可用于在应用程序启动或停止时执行某些任务。
以下是JSF 2.0中的一些重要Event Handler :
S.No | 事件处理程序和描述 |
---|---|
1 | valueChangeListener 当用户在输入组件中进行更改时,将触发值更改事件。 |
2 | actionListener 当用户单击按钮或链接组件时,将触发操作事件。 |
3 | 应用事件 在JSF生命周期中触发的事件:PostConstructApplicationEvent,PreDestroyApplicationEvent,PreRenderViewEvent。 |
JSF - JDBC Integration
在本文中,我们将演示如何使用JDBC在JSF中集成数据库。
以下是运行此示例的数据库要求。
S.No | 软件和描述 |
---|---|
1 | PostgreSQL 9.1 开源和轻量级数据库 |
2 | PostgreSQL JDBC4驱动程序 PostgreSQL 9.1和JDK 1.5或更高版本的JDBC驱动程序 |
将PostgreSQL JDBC4驱动程序jar放在tomcat web服务器的lib目录中。
Database SQL Commands
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;
例子 Example Application
让我们创建一个测试JSF应用程序来测试JDBC集成。
步 | 描述 |
---|---|
1 | 在com.iowiki.test包下创建一个名为helloworld的项目,如JSF - First Application一章中所述。 |
2 | 在src → main文件夹下创建resources文件夹。 |
3 | 在src → main → resources文件夹下创建css文件夹。 |
4 | 在src → main → resources → css文件夹下创建styles.css文件。 |
5 | 修改styles.css文件,如下所述。 |
6 | 修改pom.xml ,如下所述。 |
7 | 在Author.java包下创建Author.java ,如下所述。 |
8 | 在包com.iowiki.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.iowiki.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.iowiki.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.iowiki.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://localhost/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 - First Application章节中那样编译和运行应用程序。 如果您的应用程序一切正常,这将产生以下结果。
JSF - Spring Integration
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框架提供的ContextLoaderListener和RequestContextListener监听器。
<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.iowiki.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.iowiki.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();
}
}
例子 Example Application
让我们创建一个测试JSF应用程序来测试spring集成。
步 | 描述 |
---|---|
1 | 在com.iowiki.test包下创建一个名为helloworld的项目,如JSF - First Application一章中所述。 |
2 | 修改pom.xml ,如下所述。 |
3 | 在WEB-INF文件夹中创建faces-config.xml ,如下所述。 |
4 | 修改web.xml ,如下所述。 |
5 | 在WEB-INF文件夹中创建applicationContext.xml ,如下所述。 |
6 | 在包com.iowiki.test下创建MessageService.java ,如下所述。 |
7 | 在包com.iowiki.test下创建MessageServiceImpl.java ,如下所述。 |
8 | 在包com.iowiki.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.iowiki.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.iowiki.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.iowiki.test.MessageServiceImpl">
<property name = "message" value = "Hello World!" />
</bean>
</beans>
MessageService.java
package com.iowiki.test;
public interface MessageService {
String getGreetingMessage();
}
MessageServiceImpl.java
package com.iowiki.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.iowiki.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 - First Application章节中那样编译和运行应用程序。 如果您的应用程序一切正常,这将产生以下结果。
JSF - Expression Language
JSF提供了丰富的表达式语言。 我们可以使用#{operation-expression}表示法编写正常操作。 以下是JSF表达式语言的一些优点。
可以引用bean属性,其中bean可以是存储在请求,会话或应用程序范围中的对象,也可以是托管bean。
提供对集合元素的轻松访问,可以是列表,映射或数组。
提供对预定义对象(如请求)的轻松访问。
算术,逻辑和关系运算可以使用表达式语言完成。
自动类型转换。
将缺少的值显示为空字符串而不是NullPointerException。
例子 Example Application
让我们创建一个测试JSF应用程序来测试表达式语言。
步 | 描述 |
---|---|
1 | 在com.iowiki.test包下创建一个名为helloworld的项目,如JSF - First Application一章中所述。 |
2 | 修改com.iowiki.test包下的UserData.java ,如下所述。 |
3 | 修改home.xhtml ,如下所述。 保持其余文件不变。 |
4 | 编译并运行应用程序以确保业务逻辑按照要求运行。 |
5 | 最后,以war文件的形式构建应用程序并将其部署在Apache Tomcat Webserver中。 |
6 | 使用适当的URL启动Web应用程序,如下面的最后一步所述。 |
UserData.java
package com.iowiki.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 - First Application章节中那样编译和运行应用程序。 如果您的应用程序一切正常,这将产生以下结果。
JSF - Internationalization
国际化是一种技术,其中状态消息,GUI组件标签,货币,日期不在程序中硬编码。 相反,它们存储在资源包中的源代码之外并动态检索。 JSF提供了一种处理资源包的非常方便的方法。
需要以下步骤来内化JSF应用程序。
第1步:定义属性文件
为每个区域设置创建属性文件。 名称应为
文件名中可以省略默认语言环境。
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.iowiki.messages</base-name>
<var>msg</var>
</resource-bundle>
</application>
第3步:使用resource-bundle var
home.xhtml
<h:outputText value = "#{msg['greeting']}" />
例子 Example Application
让我们创建一个测试JSF应用程序来测试JSF中的国际化。
步 | 描述 |
---|---|
1 | 在com.iowiki.test包下创建一个名为helloworld的项目,如JSF - First Application一章中所述。 |
2 | 在src → mai文件夹下创建resources文件夹。 |
3 | 在src → main → resources文件夹下创建com文件夹。 |
4 | 在src → main → resources → com文件夹下创建iowiki文件夹。 |
5 | 在src → main → resources → com → iowiki文件夹下创建messages.properties文件。 按照以下说明修改它。 |
6 | 在src → main → resources → com → iowiki文件夹下创建messages_fr.properties文件。 按照以下说明修改它。 |
7 | 在WEB-INFf创建faces-config.xml ,如下所述。 |
8 | 在包com.iowiki.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.iowiki.messages</base-name>
<var>msg</var>
</resource-bundle>
</application>
</faces-config>
UserData.java
package com.iowiki.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 - First Application章节中那样编译和运行应用程序。 如果您的应用程序一切正常,这将产生以下结果。
从下拉列表中更改语言。 您将看到以下输出。