从请求范围Bean上的JSF数据表中删除

时间:2014-05-05 14:46:29

标签: spring jsf jsf-2.2

我有一个带有dataTable的页面,该页面根据查询参数填充(例如usernamepagenum)。表中的每个条目都有一个delete commandButton

pagenum != 0并且我们点击删除时,将显示要显示的记录列表" apply"相。在此阶段,视图参数尚未设置,因此记录列表为空,因此不会删除任何内容(我们的删除方法不会被调用)

为了解决这个问题,我添加了一个@PostConstruct方法,该方法从Servlet请求中检索查询参数并设置bean中的值,因此当我们获取离开记录列表时它们可用,这允许我调用我的删除方法。

我确定JSF有更好的方法来处理这种情况,@PostConstruct解决方法是黑客攻击。

实现此方案的正确方法是什么,而不依赖于View或Session范围的bean?

当然必须有一种方法可以只发布表单并删除相应的记录,而不必浪费时间重新生成记录列表。

2 个答案:

答案 0 :(得分:3)

  

实现此方案的正确方法是什么,而不依赖于View或Session范围的bean?当然必须有一种方法只需POST表单并删除相应的记录,而不必浪费时间重新生成记录列表

抱歉,没办法。至少在标准<h:commandButton>内使用标准<h:dataTable>时不会。这是JSF的状态性质的结果。 JSF只是想确保在处理回发期间视图与生成HTML输出时的视图完全相同。

这是JSF防止篡改请求的一部分,其中最终用户/黑客可以以这样的方式操纵请求参数,使得它可以做出危险的事情,例如:更改要删除的条目的ID,或绕过对rendered属性等的检查。如果JSF没有为您执行此操作并且容易被忽略,那么您将/应该进行其他预验证的所有内容由初学者(然后他们会责怪JSF不安全而不是自己)。另请参阅Why JSF saves the state of UI components on server?commandButton/commandLink/ajax action/listener method not invoked or input value not updated

如果<h:commandButton>位于<h:dataTable>内,则JSF只需要在应用请求值阶段提供数据模型,以便它可以迭代组件树中的<h:dataTable>为了找到按下的按钮并排队动作事件。如果没有数据模型,则无法找到按下的按钮,动作事件将不会排队。通常,这可以通过将托管bean放在JSF视图范围内来解决。另请参阅How to choose the right bean scope?

对于请求范围的bean,<f:viewParam>确实不是在应用请求值阶段之前保留数据模型的正确工具。您需要使用@PostConstruct带注释的方法来完成工作。在JSF托管bean的情况下,请求参数可以通过@ManagedProperty注入。另见ViewParam vs @ManagedProperty(value = "#{param.id}")。对于CDI或Spring托管bean,没有标准注释可用于将HTTP请求参数作为bean属性注入。对于CDI,JSF实用程序库OmniFaces具有@Param用于此目的。另见OmniFaces @Param showcase。对于Spring,你需要自己进行自己的生成。我,non-Spring-user然而不知道如何做到这一点。谷歌似乎也没有多少透露。

或者,您也可以通过@ViewScoped将bean放在视图范围内。只要您回发到同一视图,它就会存在。 JSF 2.2具有与javax.faces.view包中的CDI兼容的注释。 javax.faces.bean包中的那个是@ManagedBean的旧JSF 2.0 / 2.1注释。 Spring没有注释,因为否则会依赖于JSF API。你需要自己移植它。 Google显示several examples

答案 1 :(得分:1)

  

实施此方案的正确方法是什么

在执行支持bean上的任何逻辑之前,JSF 始终必须重建视图以获取有关执行内容的信息。为了显示和更新目的,最好(和正确)的解决方案肯定是@ViewScoped

  

不使用View或Session范围的bean?

如果您坚持使用@RequestScoped,我会说那里没有正确的方式,但是解决方法或黑客行为。一种方法是使用您提到的@PostConstruct方法初始化列表。另一种方法是使用JavaScript函数作为删除按钮的onclick属性。例如,JS函数将使用URL来请求删除服务器。或者,您也可以使用PrimeFace's RemoteCommand作为JS函数。