什么是jsf
JavaServer Faces(JSF)是Java标准技术,用于构建基于组件的,面向事件的Web界面。 与JavaServer Pages(JSP)一样,JSF允许访问服务器端数据和逻辑。 与JSP本质上是一个具有服务器端功能HTML页面不同,JSF是一个XML文档,它表示逻辑树中的正式组件。 JSF组件由Java对象作为后盾,这些Java对象独立于HTML并且具有Java的全部功能,包括访问远程API和数据库。
诸如JSF之类的框架的关键思想是封装(或包装 )诸如HTML,CSS和JavaScript之类的客户端技术,从而使开发人员能够构建Web界面而无需与这些技术进行过多交互。
本文简要介绍了JSF的Java Web应用程序基于组件的UI开发方法。 简单的示例介绍了JSF的MVC架构,事件模型和组件库。 示例包括JSF 2.3中的新功能,并且我们将使用PrimeFaces作为组件库。
不断发展的JSF
长期流行的JSF最近面临来自与Java兼容的Web框架(包括客户端JavaScript框架)的竞争。 尽管如此,JavaServer Faces仍然是Java标准,尤其是对于大规模Java企业开发而言 。 JSF规范还产生了许多框架和库,它们与最新的客户端改进保持同步。 其中之一是PrimeFaces,我们将在本教程中进行探讨。
虽然未来的开发计划尚不清楚,但是JSF 2.3在等待我们的过程中为开发人员提供了很多工作。 JSF 2.3于2017年3月发布,旨在对JSF进行现代化改造。 在数百个小规模的修复和较大的更新中 ,JSF 2.3弃用了托管bean批注,转而支持CDI,我将在本教程的后面部分介绍。
雅加达EE中的JSF 2.3
2017年9月, Oracle宣布了将Java EE迁移到Eclipse Foundation的意图 。 此后,Java EE已更名为Jakarta EE ,并且继续采用 JSF 2.3(Eclipse Mojarra)。 JSF规范的下一个主要版本将是Eclipse Mojarra 3.0 。
在JSF中构建基于组件的Web界面
JSF的核心思想是将功能封装到可重用的组件中。 这类似于JSP中使用的可重用标签,但JSF组件更为正式。
虽然可以在JavaServer Pages中使用JSF页面,但更常见的是使用Facelets构建独立的JSF页面。 Facelets是设计用于定义JSF接口的XHTML页面。 通过Facelets,您可以使用XML标记创建一个组件树,该树成为JSF用户界面的支架。
清单1展示了使用Facelets编写的简单JSF页面的主要部分。 在这个例子中,我们通过一个通过CDI放置在作用域中的bean访问Java的服务器端功能。 稍后您将了解有关CDI的更多信息。
清单1. JSF示例页面
<lt;!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<lt;html xmlns=http://www.w3.org/1999/xhtml xmlns:h="http://xmlns.jcp.org/jsf/html" >
<lt;h:head>
<lt;title>Hello JavaWorld!<lt;/title>
<lt;/h:head>
<lt;body>
#{javaBean.content}
<lt;/body>
在清单1中,我们看到了一个标准的XHTML页面。 Facelets视图建立在XHTML之上。 除了XHTML名称空间之外,还定义和引用了一个辅助名称空间。
h
库包含在JSF HTML页面中使用的标准组件。 http://xmlns.jcp.org/jsf/html
库定义了JSF组件的集合,在这种情况下,是公共HTML元素的集合。 这些组件之一是<h:head>
元素。
JSF中HTML组件
在语法方面,清单1的<h:head>
元素引用带有h
前缀的jsf/html
库。 然后,它引用库中的特定组件,即head
组件。
<h:head>
组件输出HTML head元素。 (所有这些语法对于这样一个简单的目的来说似乎都是过分的,但是有充分的理由,正如您很快就会看到的那样。)
嵌套组件
头部内部嵌套了一个标准HTML <title>
元素。 此元素与嵌套在其中的子元素内容一起提供给<h:head>
组件。
在文档主体中,JSF表达式包含在#{}
语法中。 这与${}
格式的JSP表达式完全类似:它允许访问范围内的Java对象和简单函数。
JSF的基本模式很简单:使用Facelets构建引用组件库的XML树,然后使用库中的组件将Java对象呈现为HTML。
在JSF中使用Java对象
回到清单1,请注意,在执行此标记时,在JSF表达式( ${javaBean.content
)内, javaBean
对象在作用域内。 Facelets的XHTML访问javaBean
对象上的.content
属性。 最终输出是一个Web界面,该界面将Facelets视图结构与Java的服务器端数据和逻辑功能合并在一起。
使用JSF表达式只是从JSF用户界面访问Java应用程序数据的一种方法。 最终,您将要探索JSF组件与Java后端交互的其他方式-诸如数据列表和网格以及各种输入控件之类的东西。 到目前为止,已经足够了解JSF如何使用XML标记(或注释)来创建组件树,该组件树根据Java对象中包含的数据输出HTML。
注释与XML
使用JSF 2.3,可以使用批注定义JSF组件,从而完全避开XML元数据。 完全可以定义和部署JSF应用程序,而无需编辑任何XML。
JSF应用程序的结构
与JavaServer Pages和Servlet API一样 ,JavaServer Faces也需要标准的目录结构和元数据。 这些被部署为.war文件。
.war文件的结构类似于Servlet或JSP应用程序。 它包含一个/web-app
目录,其中包含应用程序的标记文件(在本例中为HTML,JSP和Facelets),以及一个/WEB-INF
目录,该目录提供了描述应用程序的元数据。
服务JSF
尽管您可以在Glassfish之类的Java EE容器中运行JSF,但实际上只需要一个简单的servlet容器 。 Tomcat是JSF和其他服务器端Java技术的流行容器。
JSF 2.3:规范和实现
Java的优势之一是它基于标准,并且这些标准由开放源代码社区流程控制。 自成立以来,Java Community Process(JCP)一直监督Java技术的发展。 一旦规范或规范改进得到JCP的开发和批准,就可以由多方实施。 直到最近,Servlet,JSP和JSF都是使用JCP的开源规范过程开发的。
截至撰写本文时,最新的JSF规范是JSF 2.3 ,于2017年作为Java EE 8的一部分发布。Oracle(现为Eclipse的) Mojarra是JSF参考实现,而MyFaces和PrimeFaces是受欢迎的第三方实现。
这些框架中的每一个都实现JSF核心,其中包括一些标准组件。 供应商还可以在标准之上提供其他组件库。 在评估JSF框架时,最好考虑一下应用程序的需求以及可用的组件库来帮助您构建它。 理想情况下,您的JSF框架应立即使您尽可能接近所需。
JSF 2.3中的MVC
JSF是一个MVC框架 ,实现了model-view-controller模式 。 在MVC模式中,其想法是将UI的三个关注点分离为谨慎的部分,因此更易于管理。 通常, 视图负责显示模型中的数据,而控制器负责设置模型并将用户路由到正确的视图。
在JSF实现中,视图是Facelets页面及其XML标签集。 这些定义了用户界面的布局。 使用JSF的另一半是服务器端,其中Java类支持这些UI组件。
JSF 2.3中不推荐使用的托管bean
JSF 2.3中已弃用了托管bean批注,并已将其替换为CDI( 上下文和依赖注入 )。 使用CDI,开发人员可以定义上下文并将对象注入该上下文。 那些熟悉托管bean的人会发现注释语法略有不同,但是语义仍然完全相同。
控制器豆
在JSF 2.3中,控制器bean提供了MVC方程式的控制器部分。 普通的Java对象(通常称为POJO或普通的Java对象)提供了模型。
就流程而言,控制器Bean:
- 确定将用户请求定向到哪里
- 为模型设置POJO
- 使用模型渲染Facelets视图
然后,JSF将组件树和模型折叠在一起以呈现输出HTML。
清单2显示了如何使用CDI定义清单1中的javaBean
对象。 此清单假定应用程序在其依赖项中包含cdi-api-1.2.jar。
清单2.使用CDI定义的JavaBean
import javax.inject.Named;
import javax.enterprise.context.SessionScoped;
@Named
@ViewScoped
public class JavaBean implements Serializable {
private String content = ìWelcome to JSF!î
// getters/setters
}
带有PrimeFaces的JSF 2.3
在下一部分中,我将使用PrimeFaces向您展示JSF如何实现MVC模式,事件驱动的消息传递和可重用组件。 首先,打开PrimeFaces Showcase ,单击左侧列中的Data链接,然后选择DataList 。 这将调出PrimeFaces的DataList演示代码。
图1显示了在哪里可以找到这些样本。
图2显示了一个简单数据表的输出,该表取自PrimeFaces DataList演示。
PrimeFaces DataList:访问数据模型
清单3给出了此dataList
显示的标记。 如果滚动到PrimeFaces展示柜的底部,则可以在dataList.xhtml
选项卡中看到标记。
清单3. PrimeFaces DataList的Facelet
<p:dataList value="#{dataListView.cars1}" var="car" type="ordered">
<f:facet name="header">
Basic
</f:facet>
#{car.brand}, #{car.year}
</p:dataList>
在清单3中,请注意dataList
组件的value
属性。 您可以看到它引用了dataListView
对象,并访问它的.cars1
属性。 该组件将使用该字段返回的模型对象。 JSF令牌使用常规访问器来引用对象属性,因此.cars1
将引用对象上的getCars()
getter。
接下来,请注意var="car"
属性。 这告诉dataList
组件在迭代value
字段返回的汽车列表时要使用什么变量。 这些属性特定于dataList
组件,但value
属性非常常见。 var
属性对于迭代列表的组件也是常规的。
在清单3的组件主体中,您可以看到可以通过诸如#{car.brand}
类的JSF表达式访问car
变量。 dataListView.cars1
实例的每次迭代将输出car.brand
字段。
注意, <f:facet...>
标记演示了自定义组件以使其显示方式的功能。 在这种情况下,标头定义为Basic
。
您可以通过将数据与标记结合起来,了解Facelets XML将如何驱动此输出。 现在让我们看一下它背后的Java代码。
DataList的服务器端组件
清单4显示了DataListView
,清单3中的标记使用了Java类。您将很快看到dataListView
实例如何与DataListView
类相关联。
清单4. DataListView类
package org.primefaces.showcase.view.data;
import java.io.Serializable;
import java.util.List;
import javax.annotation.PostConstruct;
import javax.inject.Named; // Pre JSF 2.3, this was:
// import javax.faces.bean.ManagedBean;
import javax.inject.Inject;
import javax.faces.bean.ViewScoped;
import org.primefaces.showcase.domain.Car;
import org.primefaces.showcase.service.CarService;
@Named
@ViewScoped
public class DataListView implements Serializable {
private List<Car> cars1;
private Car selectedCar;
@Inject("#{carService}")
private CarService service;
@PostConstruct
public void init() {
cars1 = service.createCars(10);
}
public List getCars1() {
return cars1;
}
public void setService(CarService service) {
this.service = service;
}
}
清单4还有一些其他重要元素,我们将逐一考虑。
依赖注入和注释
首先,请注意DataListView
类使用@Named
注释,您可以从import import javax.inject.Named;
看到它import javax.inject.Named;
是JSF的一部分。 @Named
注释告诉JSF此bean是应用程序的一部分。 @ViewScoped
批注告知JSF,Bean将在视图的整个生命周期内都存在。
接下来,观察CarService
属性具有@Inject
注释(在JSF 2.3之前称为@ManagedProperty
)。 这是JSF的另一项功能,它允许将bean“连接在一起”,这是一种由Spring框架和其他依赖项注入工具普及的技术。 本质上,JSF将在范围内找到carService
对象,并将其自动关联到DataListView
对象上的service
字段。
翻译自: https://www.infoworld.com/article/3322533/what-is-jsf-introducing-javaserver-faces.html
什么是jsf