JSF: Bean作用域;会话与请求的区别

6
我有一个名为UserSearchHandler的托管Bean,它有一个doSearch方法,该方法填充了UserSearchHandler.searchResults,这些结果在userSearch.xhtml页面上以表格形式显示。
我还有另一个托管Bean,名为UserHandler,它有一个showUser方法等等。
在搜索结果表中,用户名是一个链接,当单击时,应该在userView.xhtml页面上显示用户详细信息。表格和链接如下所示:
<p:dataTable var="user" value="#{userSearchHandler.searchResults" >

// ... and so on ... then

<h:commandLink value="#{user.firstName}" action="#{userHandler.showUser}">
  <f:setPropertyActionListener target="#{userHandler.userIdToShow}" value="#{profile.id}"/>
</h:commandLink>

当托管的 bean 被设置为 session 作用域时,一切都正常运行。

但是,当我将 bean 的作用域更改为 request 时,搜索功能可以正常工作并填充表格,但是当我单击名称链接时,没有任何反应。我在 userSearchHandler 被设置为 "request" 作用域时,在 userHandler.showUser 方法上放置了一个断点,但它从未被触发。

有没有人能够帮忙解释为什么会出现这种情况,或者我做错了什么?

2个回答

5
这是因为在新请求期间,#{userSearchHandler.searchResults}为空,因此JSF无法定位与命令链接相关联的行以调用操作(并传递/设置属性,如果有的话)。
您需要确保在bean的构建/初始化过程中预先创建相同的#{userSearchHandler.searchResults}。如果它是基于特定参数集创建的,则必须将它们与表单一起传递。
这正是Tomahawk的<t:saveState />和新的JSF 2.0视图范围等解决方案存在的原因。
另请参见:
- JSF 2.0的主要缺点是什么?

谢谢!有没有办法让它在不将UserSearchHandle设置为会话作用域bean的情况下工作? - user550738
1
如果您使用的是JSF 2.0,则将bean放在视图作用域中即可。如果您仍然使用JSF 1.x,请考虑Tomahawk的“t:saveState”(不确定PrimeFaces是否提供类似的内部解决方案,因为我从未在JSF 1.x上使用过PrimeFaces)。 - BalusC
再次感谢。我正在使用JSF2。还有更多问题。:)阅读关于视图范围的内容,在我的情况下,我在单击时加载一个新页面"userView.xhtml"。视图范围会在这里起作用,还是我需要停留在同一页上才能起作用?另外,我正在使用Spring IoC,因此我正在使用Spring注释来创建托管bean,例如"@Scope("session")",那里似乎没有"@Scope("view")"选项。 - user550738
当将一个字段标记为“transient”时,它不会被序列化,因此在反序列化后也不可用。所以你使用得很正确,但是UserService似乎也是一个JavaBean,因此它确实需要被序列化。这只是按照契约来的。 - BalusC
Java EE/EJB默认是事务性的。请注意,t:saveState也需要bean可序列化...(请参见早期评论)。如果会话范围或可序列化确实不是选项,那么您必须在bean的构造函数或@PostConstruct中根据这些参数调整请求参数并准备数据模型。 - BalusC
显示剩余5条评论

0

除非您添加了<redirect/>,否则默认情况下导航不会触发新请求。它只是在幕后使用RequestDispatcher#forward()。提交表单(纯客户端交互的按下commandlink/commandbutton)负责新请求。 - BalusC
我用尖括号输入了redirect/,但它没有显示在我的答案中。对此我感到很抱歉。我想说的是我无法确定是否正在使用重定向。我在《JavaServer Faces 2.0完全参考》中读到,按下没有包含重定向或不包含?faces-redirect=true的导航规则的commandButton/Link将仅发布表单值,而浏览器不会向新URL发出第二个HTTP请求的隐式导航。 - Sean
相反,浏览器将只会呈现新页面,并且请求作用域 Bean 中的值仍然可用。但是我比较新手,所以很可能我对所读的内容有误解。我会重新阅读它。 - Sean

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接