404mj.diandian.com/post/2014-03-30/40061399791
Seam组件模型是为使用事件驱动的应用程序而开发的,特别是在一个细粒度的事件模型里进行细粒度的松耦合组件的开发。 Seam的事件有几种类型,大部分是我们已经见过的:
-
JSF事件
-
jBPM的转换事件
-
Seam页面动作
-
Seam组件驱动事件
-
Seam上下文事件
1、页面动作
Seam的页面动作是指就在我们渲染页面之前发生的事件。我们在 WEB-INF/pages.xml 中声明页面动作。 我们可以为任何一个特殊的JSF视图id定义一个页面动作:
<pages> <page view-id="/hello.jsp" action="#{helloWorld.sayHello}"/></pages>
或者,我们可以使用一个通配符 * 作为 view-id 的后缀来指定一个动作,应用到所有符合该模式的视图ID中:
<pages> <page view-id="/hello/*" action="#{helloWorld.sayHello}"/></pages>
如果多通配符的页面动作匹配当前的view-id,Seam将按照从最不具体的到最具体的顺序来调用所有的动作。
页面动作方法可以返回一个JSF的结果。如果这个结果非空,Seam将用定义好的导航规则导航到一个视图中去。
对于多页面或者条件页面的动作,可以使用 <action> 标签指定:
<pages> <page view-id="/hello.jsp"> <action execute="#{helloWorld.sayHello}" if="#{not validation.Failed}"/> <action execute="#{hitCount.increment}"/> </page></pages>
1.1.1 页面参数
一个JSF faces请求(表单提交)同时封装了一个“动作action”(一个方法绑定)和“多个参数parameters”(输入值绑定)将请求参数映射到模型
Seam让我们提供一个值绑定,来将一个已命名的请求参数映射成一个模型对象的属性。
<pages> <page view-id="/hello.jsp" action="#{helloWorld.sayHello}"> <param name="firstName" value="#{person.firstName}"/> <param name="lastName" value="#{person.lastName}"/> </page> </pages>
<param> 的声明是双向的,就像一个JSF输入的值绑定:
-
当视图id的一个non-faces(GET)请求发生时,Seam在执行了相应的类型转变之后,就在模型对象上设置已命名的请求参数的值。
-
任何 <s:link> 或 <s:button> 很明显是含有请求参数。 参数的值由渲染阶段(当 <s:link> 被渲染)的值绑定来决定。
-
使用 <redirect/> 到视图id的任何导航规则很明显是含有请求参数。 参数的值由调用应用程序阶段结束时的值绑定大小来决定。
-
这个值很明显是由带有视图id的被提交的任何JSF页面传播的。 这意味着视图参数表现得就像faces请求的 PAGE 范围内上下文变量一样。
最理想的情形是无论我们从什么页面到 /hello.jsp (或者从/hello.jsp回到/hello.jsp), 在值绑定中被引用的模型属性的值都应该被“记住”,而不需要做什么转换(或者其他的服务器端状态操作)。
1.1.1.2. 传播请求参数
如果只是指定 name 属性,那么请求参数就会利用 PAGE 进行上下文传播(它没有被映射成模型属性)。
<pages> <page view-id="/hello.jsp" action="#{helloWorld.sayHello}"> <param name="firstName" /> <param name="lastName" /> </page> </pages>
如果你想要建立多层详细的CRUD页面,页面参数的传播尤其有用。你可以用它“记住”你前面到过的页面(例如当按了保存按钮时)和正在编辑的实体。
-
很明显,如果参数是视图的页面参数的话,任何 <s:link> 或者 <s:button> 都会传播请求参数。
-
这个值很明显是由带有指定视图id的页面的任何jsf页面表单提交传播的。 (这意味着视图参数表现得就像faces请求的PAGE范围内视图参数一样。)
所有这些听起来很复杂,你可能会想这么一个外来的构造是否真的值得去努力。实际上,一旦你“掌握了它”,有这种想法非常自然。 理解这些资料显然需要花费时间的。页面参数是跨越non-faces请求来传播状态的最优雅方式。 对于用可标记的结果页,搜索屏幕的问题尤其有效,在这种情况下,我们喜欢可以写应用程序代码、用同一段代码来处理POST和GET请求。 页面参数消除了视图定义中请求参数的重复清单,并使得重定向更容易用代码实现。
1.1.1.3. 转换和验证
<pages> <page view-id="/calculator.jsp" action="#{calculator.calculate}"> <param name="x" value="#{calculator.lhs}"/> <param name="y" value="#{calculator.rhs}"/> <param name="op" converterId="com.my.calculator.OperatorConverter" value="#{calculator.op}"/> </page></pages>
或者:
<pages> <page view-id="/calculator.jsp" action="#{calculator.calculate}"> <param name="x" value="#{calculator.lhs}"/> <param name="y" value="#{calculator.rhs}"/> <param name="op" converter="#{operatorConverter}" value="#{calculator.op}"/> </page></pages>
JSF验证器和 required="true" 也可以这样用:
<pages> <page view-id="/blog.xhtml"> <param name="date" value="#{blog.date}" validatorId="com.my.blog.PastDate required="true"/> </page></pages>
<pages> <page view-id="/blog.xhtml"> <param name="date" value="#{blog.date}" validator="#{pastDateValidator}" required="true"/> </page></pages>
更好的方式,基于模型的Hibernate验证器注解会自动被识别和验证。
当类型转换或者验证失败后,一个全局的 FacesMessage 就会被添加到 FacesContext 中。
<action execute=“”>执行某动作。