在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 JBoss Seam JBoss Seam
JBOSS SEAM组件中文手册 Seam_2.0_Reference_zh_CN
整理自jboss seam 中文站,压缩为chm格式,便于广大jboss seam爱好者阅读,所有版权归jboss seam中文站所有。
Jboss Seam中文参考手册,通过大量的实例详细介绍seam的使用
[TipTec Development] JSF & Facelets & JBoss Seam 核心技术 (英文版) [TipTec Development] Essential JSF, Facelets & JBoss Seam (E-Book) ☆ 出版信息:☆ [作者信息] Kent Ka Iok Tong [出版机构] TipTec ...
jbossseam eclipse安装 例子学习.doc jfreechart flex
jboss seam 参考,英文, seam包内的参考文档
Seam为持久化集成了JPA和Hibernate 3,为轻量化的异步性集成了EJB Timer Service和Quartz,为工作流集成了jBPM,为业务规则集成了JBoss规则,为电子邮件集成了Meldware Mail,为完整的文本搜索集成了Hibernate ...
jboss seam 和jsf2 开发好书
JBOSS_SEAM配置
java jboss seam jboss-seam-selectitems
Seam为你的应用程序中所有的业务逻辑定义了一种统一的组件模型。 Seam组件可能是有状态的,包含与几个定义良好的上下文中任何一个相关联的状态, 包括长时间运行上下文、持久化上下文、业务流程上下文, 以及用户...
个人收集整理的最全面seam文档 包括seam_reference(中、英) richfaces jsf a4j 以及seam一些其他主要功能
jboss -seam 绝对有用教程,
JBoss Seam的简介 入门开发的领路杰作
一份非常好的seam简介,简明扼要,有开发的例子介绍。
CJ电子书系列(1) 网上一篇介绍JBoss Seam的好文深入浅出《JBoss Seam》,有人把它翻译成中文,我把它制作成PDF,希望更多的人能够读到更好的java 技术文章。
深入浅出JBoss Seam 作者 Michael Yuan 译者 包亮 本文节选了Michael Yuan和Thomas Heute所著的即将出版JBoss Seam: Power and Flexibility Beyond Java EE 5.0第一章和第二章,内容有所删减。
[Apress] JSF 2 APIs & JBoss Seam 基础教程 (英文版) [Apress] Beginning JSF 2 APIs and JBoss Seam (E-Book) ☆ 出版信息:☆ [作者信息] Kent Ka Iok Tong [出版机构] Apress [出版日期] 2009年05月25日 ...
jboss教程 深入浅出JBoss+Seam