[英]Elegant handling of attributes without a session bean
I'm working on an application using JSF 2.0 and Richfaces 4, that consists of many tables that display elements and of course, the usual View/Edit/Delete options. 我正在使用JSF 2.0和Richfaces 4开发一个应用程序,该应用程序包含许多显示元素的表,当然还有通常的View / Edit / Delete选项。 After some SO browsing and Google search I've decided to post a question because the answers I found did not solve my problem. 经过一些SO浏览和Google搜索后,我决定发布一个问题,因为我发现的答案不能解决我的问题。
Right now, and going straight to the point, my application is having issues when handling certain attributes that are stored in request beans and, on certain points, are lost due to successive requests. 现在,直截了当地,我的应用程序在处理存储在请求Bean中的某些属性时遇到问题,并且在某些方面由于连续的请求而丢失。
For example, when I want to edit an object, the object is sent (f:propertyActionListener) to a request bean that displays the data on a form, then it is discarded as that request ends. 例如,当我要编辑一个对象时,该对象将被发送给(f:propertyActionListener)一个请求bean,该bean在表单上显示数据,然后在请求结束时将其丢弃。 When saving, a new object is created and the attributes on the form are setted to it and the item gets saved instead of updated, since it has no id (JPA + Hibernate). 保存时,将创建一个新对象,并将表单上的属性设置为该对象,并且将保存该项目而不是对其进行更新,因为它没有ID(JPA + Hibernate)。
I've investigated many options and this is what I've did so far and the results: 我已经研究了许多选项,这是我到目前为止所做的以及结果:
f:param + h:link or h:commandLink: With @ManagedProperty the param is null, and I can't find it on the Context to look it up through JNDI. f:param + h:link或h:commandLink:使用@ManagedProperty时,param为null,我无法在Context中找到它来通过JNDI查找它。
f:setPropertyActionListener + h:commandLink + Request Bean: Works... but I'm losing some data. f:setPropertyActionListener + h:commandLink +请求Bean:有效 ...但是我丢失了一些数据。 The form that displays the data has some conditionally rendered fields and I can't hold that info, so the form is messed if the validation phase finds invalid data. 显示数据的表单具有一些有条件地呈现的字段,我无法保存该信息,因此,如果验证阶段发现无效数据,则表单将被弄乱。
f:viewParam + h:commandLink + View Scoped Bean: Weird stuff here. f:viewParam + h:commandLink + View Scoped Bean:这里很奇怪。 This one doesn't directly work because the bean seems to get discarded before rendering the form, because the form is rendered with no information since the bean is clean. 这个代码不能直接工作,因为该bean似乎在呈现表单之前就被丢弃了,因为该表单是干净的,因此呈现的表单没有任何信息。
Using a session bean: Works like a charm, but I don't want to make a session bean for every form just because I'm still learning things about the JSF lifecycle, I want to do it the proper way. 使用会话bean:就像一个魅力一样,但是我不想为每种表单都创建一个会话bean,只是因为我仍在学习有关JSF生命周期的知识,所以我想以正确的方式来做。
If I want to keep the Request session approach, is there a way to store a parameter (either an object or a plain string) and obtain later on a request bean?. 如果我想保留Request会话方法,是否可以存储参数(对象或纯字符串)并稍后在request bean上获取?
Dunno if this helps but I'm using a master page through ui:insert and ui:define. Dunno如果有帮助,但是我正在通过ui:insert和ui:define使用母版页。
Use a view scoped bean. 使用视图范围的bean。 It should work. 它应该工作。 The problems which you describe there suggests that you're binding it to JSTL tags or id
or binding
attributes. 您在那里描述的问题表明您正在将其绑定到JSTL标签或id
或binding
属性。 You should not do that on a view scoped bean. 您不应在视图作用域的bean上执行此操作。 See also @ViewScoped
fails in tag handlers . 另请参见@ViewScoped
在标记处理程序中失败 。 Another possible cause is that you're using CDI's @Named
to manage the bean instead of JSF's @ManagedBean
. 另一个可能的原因是您使用的是CDI的@Named
来管理Bean,而不是JSF的@ManagedBean
。 That would also explain why @ManagedProperty
doesn't work in one of your attempts as it also requires the bean to be managed by JSF's @ManagedBean
. 这也可以解释为什么@ManagedProperty
在您的一次尝试中不起作用,因为它还要求该bean由JSF的@ManagedBean
管理。
As to the master-detail page approach, use a <h:link>
with <f:param>
in the table page to create view/edit links in the master page. 对于主从页面方法,请在表页面中将<h:link>
与<f:param>
以在主页面中创建视图/编辑链接。
Eg user/list.xhtml
例如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>
The bean can be just request scoped. 该bean可以仅在请求范围内。
Then, in the defail page, which is in this case an edit page, use <f:viewParam>
to convert, validate and set the id
as User
. 然后,在默认页面(在本例中为编辑页面)中,使用<f:viewParam>
转换,验证并将id
设置为User
。
Eg user/edit.xhtml
例如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>
Use a @ViewScoped
bean to hold the data, service and action methods: 使用@ViewScoped
bean来保存数据,服务和操作方法:
@ManagedBean
@ViewScoped
public class UserEdit {
private User user;
@EJB
private UserService service;
public String save() {
service.save(user);
return "users";
}
// Getter+setter.
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.