2.3 理解组件和客户端标识符
前一节,我们接触了客户端标识符的概念,现在来看看它与在JSP中分配给组件的标识符有何不同。
我们说过,UI 组件跨越两个世界:在服务器端,它被表示为组件树中的一个对象;在客户端,它可以有多种表现形式。服务器是由一个Java虚拟机以及servlet、 JSF、应用代码和其他支持库组成。客户端则通常是能够显示诸如HTML之类的标记的浏览器。浏览器则是属于客户端脚本语言(如JavaScript或者 VBScript)、层叠样式表(CSS)之类的样式机制以及像锚和超链接之类的导航方案的世界。
在两个世界中都需要有找到特定组件的特定的方式。在服务器端,每个组件都可以通过组件标识符找到。如果你为某个组件指定了标识符,便可以在Java 代码中访问该组件。在客户端,每个组件都可以通过其客户端标识符找到,而该标识符则衍生自组件标识符。客户端标识符是允许你通过JavaScript、 CSS和其他类似技术来操作组件的表现。
客户端标识符也在服务器和客户端之间架了一座桥。当用户提交表单时,客户端标识符也随表示用户对该组件所执行的动作的数据一起发送给服务器,然后被用来将用户数据映射到服务器上的组件实例,以便修改其值,产生事件,以及进行其他一些操作。
这似乎有些含混,所以我们来看一个例子。图2-6展示了运行于服务器端的组件、它们在客户端的表示以及使用标识符的技术种类之间的关系。下面的JSP代码定义了图中所示的组件——一个 HtmlOutputText组件和一个具有两个HtmlInputText子组件的HtmlForm组件:
图2-6 服务器中的组件实例是通过组件标识符来引用的。而在客户端它们则是通过客户端标识符来引用的。有时候两者相同
首先,需要指出的是,这里的id属性是组件标识符。另外,你将注意到第一个<h:inputText>元素并没有特定的标识符。这是因为标识符是可选的——如果没有指定一个,JSF将生成一个。
注解 组件标识符必须由字母或下划线开始,并且由字母、数字、连字符和下划线组成。它们也应该简短一些,以便使返回给客户端的响应最小化。
现在,来看看对应的HTML输出:
HTML <span>元素是由HtmlOutputText组件产生的。其客户端标识符为outputText,与我们在JSP为其定义的组件标识符一样。<form> 元素是HtmlForm 组件的输出,其客户端标识符也与组件标识符相同。但是其所有子组件的客户端标识符却要以HtmlForm 组件的客户端标识符myForm开始。因为我们没有为第二个HtmlInputText组件指定组件标识符,JSF自动为其分配了一个标识符_id0(输入控件通常将id和name属性一起输出为客户端标识符)。
HtmlForm 组件的子组件的客户端标识符以HtmlForm的客户端标识符开始,因为HtmlForm组件是个命名容器。命名容器是下一节的内容。
注解 组件标识符通常是可选的,但是如果需要用一个组件引用另一个组件,或者通过已知的标识符在客户端或服务器端引用组件时,则是必要的。如果没有为其指定,JSF 将在服务器中自动产生一个,但是取决于具体的组件,你可能不能在呈现好的标记中看到客户端标识符。而如果指定了一个组件标志符,则尽可能地保持其简短,以便减小JSF响应的大小。
2.3.1 命名容器
命名容器是个组件,它的所有儿子都有唯一的组件标识符。所以不能在一个命名容器中存在两个具有相同组件标识符的组件。视图的根节点(UIViewRoot),即某个给定页面中所有组件的父亲,不是命名容器,但是的确需要使同一个视图中的顶层组件具有不同的标识符。
HtmlForm就是命名容器,所以位于同一个 HtmlForm 中的组件不能有相同的组件标识符。这是有意义的,因为如果具有两个名称都为foo的组件并且类型也相同,你将不能区分它们。另一个标准的命名容器是 HtmlDataTable。某些第三方组件(或者你自己编写的组件),也可以是命名容器。
如果在控件层次体系中有不只一个命名容器,客户端标识符可以不同于组件标识符。这是因为客户端标识符对整个页面必须保证唯一,而不管其中有多少命名组件。它们必须是唯一的,因为客户并不知道命名容器——它仅仅提交回表单数据给JSF 应用。应用必须能将数据映射到具体的组件,即必须能够区分针对某个组件的数据。
为了演示,来看看同一个视图中的两个HtmlForm组件。它们都包含一个具有相同组件标识符的HtmlInputText子组件:
这两个声明,除了HtmlForm 组件的标识符不同外,其余都是一样的。下面是与其对应的HTML输出:
UIViewRoot不产生任何输出;它仅是标明组件树的开始。然而重要的是,即便两个HtmlTextInput组件具有相同的组件标识符inputText,但其客户端标识符却是不同的。因为第一个表单的客户端标识符是firstForm,其子控件的客户端标识符则为firstForm:inputText。而后一个表单的客户端标识符是 secondForm,其子组件的客户端标识符为secondForm:inputText。如你所见,客户端标识符等于命名容器的客户端标识符加上冒号再加上其自身的组件标识符。
注解 因为客户端标识符的默认分隔符为":",这在CSS样式,试图使用客户端标识符应用样式到某个组件时,可能会出现问题。解决方法是对组件应用CSS 类样式(基于此目的,所有的标准HTML 组件都有一个styleClass属性)。
你可能想知道命名容器将如何影响JSF开发人员的日常开发工作。知道哪个组件是命名容器,将有助于你了解一个组件的客户端标识符。并且,如果你认识客户端标识符,便可以在客户端引用它,并且在服务器中为其解码,这些都可以在后面的内容中看到。
2.3.2 引用标识符
好了,现在已经知道UI组件在客户端和服务器端都有标识符,并且知道如果涉及命名容器这些标识符可能不同。现在我们来看看如何使用这些标识符在客户端和服务器引用组件。
1.客户端引用
如前所述,客户端技术可以通过客户端标识符引用组件。请看下面的JSP 代码:
这里有个HtmlForm 组件,而它又分别有两个HtmlOutputLabel 和 HtmlInputText 子组件。HtmlOutputLabel组件有一个HtmlOutput子组件。这样产生了下面的HTML代码:
label元素的onmouseout 和 onmouseover属性中的JavaScript代码,通过input字段的name 属性(clientForm:myTextBox)引用了它,该名称也是HtmlInputText 组件的客户端标识符。用户的鼠标移到label上,文本框的值将变为"84"。用户移开鼠标,它将变为空。这并不是什么很有用的功能,但从这知道,你可以在JavaScript 中通过其客户端标识符访问文本字段。
针对HTML 浏览器,组件的客户端标识符映射至对应的HTML元素的name或者id属性。这意味着也可以在CSS中使用它,或者将其作为锚引用等(关于HTML 的快速参考,请访问W3School的站点[W3Schools])。
然而,请记住JSF 并不限于是HTML应用,可以是不同类型的浏览器、桌面客户、applet或者干脆完全不同的其他东西。不管使用何种技术,运行于客户端的代码都必须考虑客户端标识符,特别是在和服务器通信时。
2.服务器端引用
当你在服务器上和JSF组件交互时,编写的代码通常位于后台bean的事件监听器方法或者事件监听器类中。然而,它可以位于任何位置,只要具有对组件实例的引用。这是因为基本组件类—— UIComponent——具有一个快捷的findComponent方法。该方法使用类似于客户端标识符的特殊表达式来查找组件。
例如,假定在JSP中定义了如下的表单:
这样就定义了一个messageForm的 HtmlForm组件,以及一个outputMessage的HtmlOutputText子组件以及没有指定标识符的 HtmlCommandButton子组件。HtmlCommandButton 引用了testForm.sendMessage 事件监听器方法,该方法是:
这里,我们首先获取视图的根组件,然后使用 HtmlOutputText 组件的客户端标识符调用findComponent方法。接下来修改了它的颜色(使用CSS样式)和值。用户点击按钮时,此方法被调用,并且在页面重新显示时,HtmlOutputText控件将以蓝色显示“Who’s the Mann?”(后台bean也可以直接引用组件,特别是由IDE产生时,所以这种查找并不是很必要)。关于findComponent方法的详细信息,参考第11章。在为了将请求参数映射到组件值而编写组件和呈现器时,你也需要使用客户端标识符。
现在,已经知道关于组件和客户端标识符的所有内容,接下来则看看JSF的另一个基本部分,在日常工作中会经常遇到:JSF表达式语言。
分享到:
相关推荐
JSF 2.0引入了复合组件的概念,它允许开发者将多个JSF组件和行为组合成一个单一的自定义组件。复合组件定义在独立的.xhtml文件中,可以包含属性、事件和嵌套组件。在使用时,只需引用这个.xhtml文件即可。 7. **...
JSF组件有六个主要阶段:恢复视图、应用请求值、处理验证、更新模型值、调用应用事件和呈现响应。在这个过程中,JSF处理用户提交的数据,进行验证,更新模型,然后渲染响应。 ### PPT演示 PPT演示通常包含详细的...
#### 四、JSF组件开发 JSF不仅支持标准的组件库,还允许开发者创建自定义组件。组件开发人员通常关注于生命周期的起始阶段和结束阶段: - **恢复视图**(Restore View): 在这一阶段,组件开发人员需要确保视图...
**2.3 理解组件和客户端标识符** - **2.3.1 命名容器**:用于组织和引用组件的容器。 - **2.3.2 引用标识符**:用于唯一标识组件的名称。 **2.4 JSF表达式语言** - **2.4.1 作用域变量**:定义了不同级别的变量...
5. **Facelets**:Facelets是JSF的默认视图技术,它是一种XML-based的模板语言,用于创建和组织JSF组件。相比早期的JSP,Facelets更易于维护和扩展。 6. **Managed Beans**:Managed Beans是JSF中的业务逻辑层对象...
JSF组件可以通过XML文件(Faces Config)进行配置,也可以在Java代码中动态创建。 JSF的工作流程包括几个关键步骤:请求处理、视图构建、模型更新和响应生成。当用户发起请求时,JSF框架解析请求参数,找到对应的...
Java Server Faces(JSF)是一种基于组件的Web应用程序开发框架,用于构建富客户端用户界面。JSF是Java EE(现在称为Jakarta ...通过深入理解和实践这些知识点,开发者能够高效地构建出健壮且用户友好的Java Web应用。
- **视图(View)**:负责显示数据,使用JSF组件库中的组件来构建用户界面。 - **控制器(Controller)**:处理用户的请求,协调模型和视图。在JSF中,`FacesServlet`扮演控制器的角色,解析请求并调用相应的后台...
2. **事件和监听器**:当用户与组件交互时,JSF会触发事件,并允许定义监听器来处理这些事件。 3. **视图和控制器**:JSF使用FacesServlet作为控制器,负责处理HTTP请求,解析视图标识符,调用适当的后台方法,然后...
- **id**: (非必填) 组件的唯一标识符,用于客户端和服务器端识别该组件。 - **immediate**: (非必填) 如果设置为`true`,则在用户激活组件时,对应的监听器和`action`方法将在生命周期早期阶段被调用,而不是在处理...
为了更进一步理解动态创建表格的灵活性,下面提供了一个额外的示例,展示了如何在表格中动态添加下拉列表和文本输入框: ```javascript function addRow_1() { if (_table_1.rows.length ) { var _tr = _table_1....
Java EE(现称为Jakarta EE)组件有四种类型,分别是Application客户端组件、Applet客户端组件、Web组件和EJB组件。每一种组件都针对不同的应用场景和功能需求。例如,Web组件运行在Web容器中,而EJB组件则运行在EJB...
### JavaEE 测验题知识点解析 #### 一、企业级应用程序的特点 - **快速适应性**:能够迅速响应业务需求的变化。...以上知识点涵盖了Java EE中的核心概念和技术细节,对于深入理解Java EE开发具有重要的意义。
- **JSF配置** (`faces-config.xml`): 配置JSF组件的交互行为。 - **EJB部署描述文件** (`ejb-jar.xml`): 配置企业级JavaBean的服务端部署细节。 - **EJB持久化部署描述文件** (`persistence.xml`): 配置数据访问层...
RichFaces 是一款基于 JavaServer Faces(JSF)框架的组件库,提供了丰富的客户端 Ajax 支持及多种 UI 组件,使得开发者能够轻松地创建出具有高度交互性的 Web 应用程序。其强大的功能、易用性以及对 Ajax 的支持,...
标题中的"arc-middleware-github-oauth...以上就是关于"arc-middleware-github-oauth"项目及其涉及的OAuth2和JSF技术的详细解释。通过理解这些概念,开发者可以有效地集成这个中间件,提供安全的GitHub登录功能给用户。
4. **使用JSF (JavaServer Faces)的FileUpload组件**: 在JSF应用中,可以使用`<h:inputFile>`组件让用户选择文件,然后使用`FileUpload`监听器处理上传。JSF会自动处理文件上传的多部分表单数据。 在实现文件上传...
8. **Session和Cookie**: Session用于在服务器端存储用户会话信息,而Cookie则在客户端存储数据,两者常用于实现用户状态跟踪和个性化设置。 9. **Filter和Listener**: Filter可以拦截请求和响应,实现如登录验证、...
**JavaServer Faces (JSF)** 是一种用于构建企业级Java Web应用程序的标准组件架构,它提供了一套基于组件的API,使得开发者可以更轻松地创建用户界面。 #### 八、数据库索引与约束 **索引:** 数据库索引类似于...