如何防止在JSF应用程序中多次调用请求范围的bean方法?

时间:2010-10-14 07:05:51

标签: jsf httpsession thread-safety

好的,对this question 的所有答案我仍然无法解决我的问题。 我有以下星座:

在JSF(1.1)webapp中,我有一个类bean的请求范围bean Bean。当用户多次快速单击commandButton以将其重定向到insult.xhtml页面时,可能会多次调用doSomethingThatTakesALittleLongerAndShouldOnlyBeDoneOnce方法(在Tomcat 6上)。我该如何防止这种情况?

...
public Bean() {
    HttpSession session = ((HttpSession) FacesContext.getCurrentInstance()
             .getExternalContext().getSession(false));
    if(session != null && session.getAttribute("done") != null) {
        doSomethingThatTakesALittleLongerAndShouldOnlyBeDoneOnce();
        session.setAttribute("done", "done");
    }
}

public void doSomethingThatTakesALittleLongerAndShouldOnlyBeDoneOnce() {
    this.bossInsult = generateBossInsult();
}

insult.xhtml:

<ui:composition xmlns:ui="http://java.sun.com/jsf/facelets"
xmlns:h="http://java.sun.com/jsf/html" xmlns:f="http://java.sun.com/jsf/core">
<html>
    <body>
    #{bean.bossInsult}
    </body>
</html>
</ui:composition>

2 个答案:

答案 0 :(得分:2)

使bean会话作用域并使用@PostConstruct注释该方法。如果您坚持保留请求作用域,请将该部分拆分为会话范围的bean,并使用@ManagedProperty将其作为请求范围bean的托管属性。

@ManagedBean
@RequestScoped
public class Bean {
    @ManagedProperty(value="#{insultBean}")
    private InsultBean insultBean;
}

@ManagedBean
@SessionScoped
public class InsultBean {
    @PostConstruct
    public void init() {
        this.bossInsult = generateBossInsult();
    }
}

然后,JSF会注意它在会话期间只创建并调用一次。


更新:抱歉,您使用的是JSF 1.x.如果它是1.2,则以下内容实现相同:

public class Bean {
    private InsultBean insultBean;
}

public class InsultBean {
    @PostConstruct
    public void init() {
        this.bossInsult = generateBossInsult();
    }
}

<managed-bean>
    <managed-bean-name>insultBean</managed-bean-name>
    <managed-bean-class>com.example.InsultBean</managed-bean-class>
    <managed-bean-scope>session</managed-bean-scope>
</managed-bean>

<managed-bean>
    <managed-bean-name>bean</managed-bean-name>
    <managed-bean-class>com.example.Bean</managed-bean-class>
    <managed-bean-scope>request</managed-bean-scope>
    <managed-property>
        <property-name>insultBean</property-name>
        <value>#{insultBean}</value>
    </managed-property>
</managed-bean>

答案 1 :(得分:0)

点击后,使用javascript禁用该按钮。