在JBoss Seam事件机制(1)概述中讲到,Seam中的页面动作发生在页面渲染之前,我们在WEB-INF/pages.xml文件中配置页面动作。我们还提到了page元素中的view-id不一定非要是JSP或者Facelet页面,这给整合其他WEB框架留了空间,并且能够让我们处理非JSF的请求。另外页面动作可以返回一个JSF输出,通过JSF输出来定制导向。除此之外,在page元素中,我们可以使用多个action元素来完成有条件的页面动作:
<pages> <page view-id="/hello.jsp"> <action execute="#{helloWorld.sayHello}" if="#{not validation.failed}"/> <action execute="#{hitCount.increment}"/> </page></pages>
页面参数
我们知道一个JSF请求(表单提交)包括(封装)了动作和参数,所以一个页面动作也许需要参数。使用GET的请求可以做书签,因为
页面参数都作为可读的请求参数处理了。但是JSF表单使用的是POST。Seam能够让我们将请求参数和模型属性相关联和映射:
<pages> <page view-id="/hello.jsp" action="#{helloWorld.sayHello}"> <param value="#{person.firstName}"/> <param name="lastName" value="#{person.lastName}"/> </page> </pages>
page元素中的param参数是双向的,就像JSF输入的值绑定一样。
当一个非Faces请求(GET)请求某个视图view-id的时候,Seam经过正确的类型转换后将请求的参数值赋给模型对象.
任何<s:link> 或者 <s:button> 都显式得包含请求参数。参数值由渲染阶段(<s:link>渲染)的值绑定计算结果来决定.
请求某个视图view-id的任何带有<redirect/>的导向规则都显式得包含请求参数 . 参数值由调用应用阶段结束时的值绑定计算来决定.
值通过任何对给定视图view-id的页面的JSF表单提交来传递. 这意味着视图参数有些类似于Faces请求中页面范围的上下文变量。
关键的思想是我们如何从另一个页面到/hello.jsp(或者从/hello.jsp又回到/hello.jsp), 在值绑定中的模型的值仍然被记住,而不需要任何的对话或者其他的服务器端的状态。
请求值的传递
如果只是name属性被指定的话,请求参数使用PAGE页面上下文(没有和模型属性映射)来传递。
<pages> <page view-id="/hello.jsp" action="#{helloWorld.sayHello}"> <param name="firstName" /> // 没有value <param name="lastName" /> </page></pages>
如果你想创建多层次主从模式的CRUD页面时,页面参数的传递就有必要了。你可以通过页面参数的传递来记住先前你在哪个视图上
(例如你在保存页面上,必须记住上个页面你正在编辑的实体)
如果参数以视图的页面参数列出的情况下,任何<s:link> 或者 <s:button> 显式的传递请求参数.
值通过任何对给定视图view-id的页面的JSF表单提交来传递. 这意味着视图参数有些类似于Faces请求中页面范围的上下文变量。
听起来太复杂了,这有必要么?当你用它的时候你就知道了。这值得下功夫去理解。页面参数是在非Faces请求间传递状态的最佳方式。如果你想让你的搜索结果页面也能做书签的话,我们就能够在同一个代码中使用它来处理POST和GET两种请求了。页面参数能够减少视图定义中请求参数列表的重复性,并且让在代码中处理重定向更加简单。
对话和验证
导向
在Seam中,你可以使用JSF的faces-config.xml文件来设置标准的JSF向导规则。但是JSF的向导规则有很多缺点:
在重定向的时候无法指定使用的请求参数.
无法根据规则来启动或者结束对话.
规则是根据动作方法返回的值来工作的,无法通过EL表达式来计算.
还有一个问题就是如果在Seam中使用标准的JSF导向,业务逻辑将散落在pages.xml和faces-config.xml两个配置文件中,很散乱。因此建议只是用pages.xml来配置页面导向。
我们看一下如何转换:
<navigation-rule> // JSF标准导向,在faces-config.xml中配置 <from-view-id>/editDocument.xhtml</from-view-id> <navigation-case> <from-action>#{documentEditor.update}</from-action> <from-outcome>success</from-outcome> <to-view-id>/viewDocument.xhtml</to-view-id> <redirect/> </navigation-case> </navigation-rule>
<page view-id="/editDocument.xhtml"> // 等价的Seam导向,在pages.xml中配置 <navigation from-action="#{documentEditor.update}"> <rule if-outcome="success"> <redirect view-id="/viewDocument.xhtml"/> </rule> </navigation> </page>
<page view-id="/editDocument.xhtml"> // 改良版1, 甚至不使用JSF返回的string <navigation from-action="#{documentEditor.update}" evaluate="#{documentEditor.errors.size}"> <rule if-outcome="0"> // 如果错误数量为0,就代表OK <redirect view-id="/viewDocument.xhtml"/> </rule> </navigation> </page>
<page view-id="/editDocument.xhtml"> // 改良版2,判断错误是否为空 <navigation from-action="#{documentEditor.update}"> <rule if="#{documentEditor.errors.empty}"> <redirect view-id="/viewDocument.xhtml"/> </rule> </navigation></page>
<page view-id="/editDocument.xhtml"> // 如果你希望编辑后,结束对话 <navigation from-action="#{documentEditor.update}"> <rule if="#{documentEditor.errors.empty}"> <end-conversation/> <redirect view-id="/viewDocument.xhtml"/> </rule> </navigation> </page>
<page view-id="/editDocument.xhtml"> // 改良版3,或者你需要将参数传递下去 // 如果我们结束了对话,后续的请求无法知道哪个document我们感兴趣,我们需要将document id作为参数传递 <navigation from-action="#{documentEditor.update}"> <rule if="#{documentEditor.errors.empty}"> <end-conversation/> <redirect view-id="/viewDocument.xhtml"> <param value="#{documentEditor.documentId}"/> </redirect> </rule> </navigation> </page>
值得注意的是:JSF对于输出返回为Null的采用特殊处理,如果返回为Null的话指向原页面(重新显示页面)。但在Seam中不太一样。
<page view-id="/editDocument.xhtml"> <navigation from-action="#{documentEditor.update}"> <rule> // 这里的规则对非Null输出是有效的,但是对Null输出无效 <render view-id="/viewDocument.xhtml"/> </rule> </navigation> </page>
需要变成:
<page view-id="/editDocument.xhtml"> // 去掉rule元素 <navigation from-action="#{documentEditor.update}"> <render view-id="/viewDocument.xhtml"/> </navigation> </page>
<page view-id="/editDocument.xhtml"> // view-id也可以使用EL表达式指定 <navigation if-outcome="success"> <redirect view-id="/#{userAgent}/displayDocument.xhtml"/> </navigation> </page>
细粒度的定义导向,页面动作和参数
如果你有很多页面动作和参数,或者有很多导向规则,你可能想使用多个文件来配置。这时候你可以使用view-id来创建响应的page.xml
文件。例如你有个view-id为/calc/calculator.jsp的页面,你可以创建calc/calculator.page.xml文件来配置,内容如下:
<page action="#{calculator.calculate}"> // 使用page元素作为根元素 <param name="x" value="#{calculator.lhs}"/> // 指定参数 <param name="y" value="#{calculator.rhs}"/> <param name="op" converter="#{operatorConverter}" value="#{calculator.op}"/></page>
分享到:
相关推荐
### JBoss Seam 2.01GA REF DOC #### 引言:JBoss Seam概览与功能介绍 JBoss Seam 是一个为简化企业级 Java 应用开发而设计的框架。它结合了 JavaServer Faces (JSF)、Java Persistence API (JPA) 和 Java ...
- **事件处理**:改进了事件处理机制,使得事件处理更为直观。 - **生命周期**:对生命周期进行了优化,提高了性能。 - **自定义组件**:支持更简单的自定义组件开发过程。 **2. 核心API** - **UIComponent**:...
- **在 Jboss4.0 下使用 Seam**:这部分介绍了如何在 JBoss 4.0 上配置和运行 Seam 应用程序。 #### 第三章:上下文相关的组件模型 这一章深入探讨了 Seam 中的上下文模型。 - **Seam 上下文**:介绍了 Seam 上下文...
- **使用“推”风格的MVC**:展示了如何使用 SEAM 的推送机制来更新数据。 #### 三、使用Seam-gen快速启动 - **准备活动**:设置开发环境。 - **建立一个新的Eclipse项目**:通过 Eclipse 创建 SEAM 项目。 - **...
- **创建动作**: 如何定义Seam中的业务逻辑单元。 - **创建表单**: 教授如何构建用户界面,并与后端逻辑相连接。 - **从现有数据库生成应用**: 介绍了基于已有数据库快速生成Seam应用的方法。 - **部署为EAR包**...
- **Understanding the code**:重点介绍如何利用 Seam 2.1 的事件系统来处理用户操作,并实现动态页面更新。 - **How it works**:解释 Seam 2.1 如何管理和分发事件,以及如何通过组件间的通信实现复杂的功能。 #...
- **在JBoss AS上运行示例**:这部分介绍了如何在JBoss Application Server上部署并运行Seam示例项目。 - **在Tomcat上运行示例**:如果选择使用Tomcat作为应用服务器,则可以参考这部分内容进行配置和部署。 - **...
- 通过Seam的页面流机制,可以灵活地控制页面之间的跳转。 ##### 1.6 一个完整的Seam应用程序:宾馆预订范例 - **介绍**: - 宾馆预订系统是一个完整的Seam应用程序实例。 - **预订系统概况**: - 描述了系统的...
- **JBoss Seam 支持**: 与 JBoss Seam 框架集成。 #### 八、与 IDE 集成 - **Eclipse**: 提供插件支持。 - **NetBeans**: 集成开发环境支持。 - **IntelliJ IDEA**: 支持集成开发环境。 #### 九、Exadel VCP 和 ...
- **JBoss Seam集成**:实现与JBoss Seam框架的无缝协作,提升应用功能性和灵活性。 - **Portlet支持**:在门户环境中部署RichFaces组件。 - **Sybase EAServer与Oracle AS/OC4J**:确保在这些服务器环境下稳定运行...
- **JBoss Seam 支持**:JBoss Seam 是一个用于构建企业级应用的强大框架,它与RichFaces 有着良好的集成关系。 - **Portlet 支持**:为了满足门户应用的需求,RichFaces 提供了Portlet 支持,确保组件可以在Portlet...
- **JBoss Seam Support**:Seam是一个流行的Java EE框架,此处讲解了如何在Seam环境中使用Richface。 - **Portlet Support**:针对portlet开发的支持情况。 - **Sybase EAServer**:在Sybase环境下使用Richface的...
Ajax4jsf提供了针对不同环境的特定配置选项,包括Web应用描述符参数、对Sun JSF RI、Apache MyFaces的支持,以及Facelets、JBoss Seam和Portlet的集成。 #### 开始使用Ajax4jsf 要开始使用Ajax4jsf,首先需要创建...
- JBoss Seam是一个用于构建企业级应用程序的框架,可与JSF和RichFaces集成。 - 配置Seam以支持RichFaces组件。 #### Portlet支持 - 富客户端组件可以在Portlet容器中运行。 - 需要确保服务器支持portlet模式,并...
- **动作和导航:** 解释了如何通过Ajax请求执行服务器端的动作和页面导航。 - **JavaScript交互:** 指导如何编写与RichFaces组件交互的JavaScript代码。 - **迭代组件的Ajax属性:** 列举了迭代组件中用于控制...
包括Web应用描述符参数、特定JSF实现的设置(如Sun JSF RI、Apache MyFaces),以及对Facelets、JBoss Seam、Portlet、Sybase EAServer、Oracle AS/OC4J等特性的支持,确保了框架的广泛适用性和灵活性。 ### ...
此外,还支持JBoss Seam等框架,以增强应用的功能性和灵活性。 ##### 2.3 支持的服务器 支持的服务器包括但不限于: - **Apache Tomcat** - **JBoss AS / WildFly** - **GlassFish** - **WebLogic** - **...