2012-04-27 62 views
1

我正在处理使用JSF 2.0和Richfaces 4的应用程序,该应用程序由许多显示元素以及通常的查看/编辑/删除选项的表组成。经过一些SO浏览和谷歌搜索后,我决定发布一个问题,因为我发现的答案并没有解决我的问题。没有会话bean的属性的优雅处理

现在,我的应用程序在处理存储在请求bean中的某些属性时遇到问题,并且在某些点上由于连续请求而丢失。

例如,当我想要编辑一个对象时,该对象被发送(f:propertyActionListener)到一个请求bean,该请求bean在表单上显示数据,然后在请求结束时将其丢弃。保存时,会创建一个新对象,并将表单上的属性设置为该对象,并且该项目将被保存而不是更新,因为它没有标识(JPA + Hibernate)。

我已经研究过多种选项,这是我到目前为止已经做了,结果:

F:参数+ H:链接或h:commandLink:随着@ManagedProperty的参数是空,我无法在上下文中找到它来通过JNDI查找它。

f:setPropertyActionListener + h:commandLink + Request Bean: Works ...但我失去了一些数据。显示数据的表单有一些有条件的呈现字段,我无法保存该信息,因此如果验证阶段发现无效数据,表单就会混乱。

f:viewParam + h:commandLink +查看作用域Bean:这里有些奇怪的东西。这个不直接工作,因为bean在呈现表单前似乎被丢弃,因为表单没有任何信息,因为bean是干净的。

使用会话bean:工程就像一个魅力,但我不想为每个表单创建一个会话bean,只是因为我仍然在学习有关JSF生命周期的事情,我想要做到恰当办法。

如果我想保持请求会话方法,是否有方法来存储参数(对象或纯字符串)并稍后获取请求bean ?.

不知道如果这有帮助,但我通过ui使用母版页:insert和ui:define。

回答

1

使用视图范围的bean。它应该工作。您在那里描述的问题表明您已将其绑定到JSTL标记或idbinding属性。你不应该在视图范围的bean上这样做。另见@ViewScoped fails in tag handlers。另一个可能的原因是,您正在使用CDI的@Named来管理该Bean,而不是JSF的@ManagedBean。这也可以解释为什么@ManagedProperty在你的尝试中不起作用,因为它也要求bean由JSF的@ManagedBean管理。

至于主细节页面方法,请在表页面中使用<h:link><f:param>以在主页面中创建视图/编辑链接。

E.g. user/list.xhtml

<h:dataTable value="#{userList.users}" var="user"> 
    <h:column>#{user.id}</h:column> 
    <h:column>#{user.name}</h:column> 
    <h:column> 
     <h:link value="Edit" outcome="edit"> 
      <f:param name="id" value="#{user.id}" /> 
     </h:link> 
    </h:column> 
</h:dataTable> 

该bean可以只是请求作用域。

然后,在默认页面(在本例中为编辑页面),使用<f:viewParam>转换,验证并将id设置为User

E.g. user/edit.xhtml

<f:metadata> 
    <f:viewParam name="id" value="#{userEdit.user}" 
     converter="#{userConverter}" converterMessage="Bad request. Unknown user." 
     required="true" requiredMessage="Bad request. Please use a link from within the system." /> 
</f:metadata> 

<h:messages /> 
<h:link value="Back to all users" outcome="users" /> 

<h:form id="user" rendered="#{not empty userEdit.user}"> 
    <h:inputText value="#{userEdit.user.name}" required="true" /> 
    ... 

    <h:commandButton value="Save" action="#{userEdit.save}"> 
     <f:ajax execute="@form" render="@form" /> 
    </h:commandButton> 
</h:form> 

使用@ViewScoped bean来保存数据,服务和操作方法:

@ManagedBean 
@ViewScoped 
public class UserEdit { 

    private User user; 

    @EJB 
    private UserService service; 

    public String save() { 
     service.save(user); 
     return "users"; 
    } 

    // Getter+setter. 
} 
+0

即使在这种情况下,是'@ ViewScoped'真是一个很好的解决方案?虽然需要多一点工作,但我通常喜欢使用'@ ConversationScoped'来避免使用后退按钮,多个选项卡/窗口和视图范围数据过期的问题。我需要写一篇关于我的想法的适当的博客文章,但现在我会引用[先前的答案](http://stackoverflow.com/questions/10098528/jsf-2-0-viewscoped-redirect-navigation-to -target-blank/10108609#10108609)。 – Brian 2012-04-27 13:08:54

+0

感谢您的帖子@BalusC!总是很高兴地阅读你的答案。至于这些选项,我们没有对您的博客上的链接指定的特定标签进行绑定,也没有将标签直接绑定到bean。在“渲染”属性上使用某些EL表达式可能会导致问题出现?我们会根据具体情况调整表格。 – Gamb 2012-04-27 15:26:11

+0

'@ ViewScoped'是否在基本的Hello World页面上失败,只有一个提交按钮,其中action方法返回'null'或'void'? – BalusC 2012-04-27 16:17:06