给出以下场景:jsf组件(例如CommandButton)呈现属性取决于应用程序范围的托管属性。由于属性在所有会话中共享,因此可能很容易发生以下情况:用户A加载jsf页面并且按钮的render属性为true,因此它将被呈现。现在用户B也加载页面,渲染属性仍然是真的。现在,用户A单击该按钮会导致该属性更改其值,并且不再呈现该按钮。用户B仍然具有旧视图,虽然现在渲染属性为false,但他可以单击该按钮,因为他在此期间没有更新他的视图。如果用户B点击按钮,现在会发生什么?
我认为按钮的动作无论如何都会被触发,因为渲染属性仅用于渲染按钮,并且一旦呈现页面就不再具有影响力。但是在做了一些测试之后,在我看来,在单击按钮后也会再次检查render属性,如果属性为false,则不执行该操作。有人能证实吗?
答案 0 :(得分:0)
免责声明:我现在忽略了这个奇怪的设计。
但是在做了一些测试之后,我觉得在点击按钮后再次检查了render属性,如果属性为false,则不执行该操作。有人可以证实这一点吗?
是的,这是对的。这是防止可能被篡改的请求的一部分,其中黑客试图模拟实际上不由服务器端呈现的动作组件的调用(例如仅在当前用户具有的时候呈现的仅管理命令按钮。管理员角色)。在处理表单提交期间,始终会重新检查rendered
(以及disabled
和readonly
)属性。
在您的特定情况下,您希望在视图范围内拥有负责rendered
属性的条件的副本,以便仅将此副本用作只要您与同一视图进行交互。这可以通过将应用程序作用域属性作为视图作用域托管bean的托管属性注入,然后在rendered
属性中引用它来实现。
@ManagedBean
@ViewScoped
public class ViewBean {
@ManagedProperty("#{appBean.rendered}")
private boolean rendered;
// ...
}
与
<h:commandButton ... rendered="#{viewBean.rendered}" />