2012-11-18 45 views
0

给定以下情形:jsf组件的(例如CommandButton)呈现属性取决于应用程序作用域的托管属性。由于该属性在所有会话中共享,因此可能会发生以下情况:用户A加载jsf页面,并且该按钮的render属性为true,因此会呈现该属性。现在用户B也加载页面,并且render属性仍然为true。现在,用户A单击导致属性更改其值的按钮,并且该按钮不再呈现。用户B仍旧有旧视图,尽管现在渲染属性为假,但他可以单击该按钮,因为在此期间他没有更新视图。如果用户B点击了按钮,现在会发生什么?更新了render属性后,jsf组件会发生什么

我以为无论如何都会触发按钮的动作,因为渲染属性只是用来渲染按钮,并且一旦渲染页面就不再有影响了。但是在做一些测试之后,我认为在点击按钮之后再次检查render属性,并且如果该属性为false,则不执行该动作。有人能证实这一点吗?

+0

为什么在第一时间将你的'rendered'属性绑定到'@ ApplicationScoped'豆?你会用这个功能达到什么样的功能要求? –

+0

在共享资源的页面上,每个用户都应该可以对资源执行操作。但是一旦这样的行为被执行一次就不应该再次执行。例如,根据资源创建一个文件。一旦文件被创建,现有的文件应该被使用,并且不应该再次创建它,因此该按钮不应该不被显示 – nico1510

+0

因此,您可以在每个应用程序部署中创建一次文件还是基于文件存在创建一次? –

回答

0

声明:现在我会忽略这个奇怪的设计。

但做了一些测试之后,在我看来,该渲染属性也被点击按钮后再次检查,如果该属性是假的话,是不是执行的操作。有人能证实这一点吗?

是的,没错。这是防止可能被篡改的请求的一部分,其中黑客试图模拟实际上不由服务器端呈现的动作组件的调用(例如,仅当当前用户具有管理员角色)。在处理表单提交期间,总是重新检查rendered(和disabledreadonly)属性。

在您的特定情况下,你想有负责在视图范围rendered属性条件的副本让你处理了同样的观点仅交互此副本将被长期使用。这可以通过将应用程序作用域属性作为视图作用域管理bean的托管属性注入,然后在rendered属性中引用它来实现。

@ManagedBean 
@ViewScoped 
public class ViewBean { 

    @ManagedProperty("#{appBean.rendered}") 
    private boolean rendered; 

    // ... 
} 

<h:commandButton ... rendered="#{viewBean.rendered}" /> 
+0

好,但我会强制用户在实际应用程序状态的(可能)过时的副本上工作。我不能使用上面描述的机制来实现对相同资源的协同工作。或者渲染属性的更新过程不够快?然后,我仍然能够在我自己的代码中捕获异常。 – nico1510

+0

在发布后执行重定向,或者手动/自动更新属性(侦听器)方法。这与速度无关,但更多的是在JSF生命周期的正确时刻。 – BalusC

相关问题