1

Ok, with all the answers to this question I'm still not able to handle my problem. I have the following constellation:

In a JSF (1.1) webapp I have a request scoped bean beanof class Bean. When the user quickly clicks a commandButton multiple times to redirect him to the insult.xhtml page the doSomethingThatTakesALittleLongerAndShouldOnlyBeDoneOncemethod may get invoked multiple times (on Tomcat 6). How can I prevent this?

...
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>
Community
  • 1
  • 1
ceggers
  • 11
  • 3

2 Answers2

2

Make the bean session scoped and annotate the method with @PostConstruct. If you insist in keeping it request scoped, split that part out into a session scoped bean and make it a managed property of the request scoped bean using @ManagedProperty.

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

and

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

Then JSF will take care that it's created and called only once during the session.


Update: sorry, you're using JSF 1.x. If it's 1.2, then the following achieves the same:

public class Bean {
    private InsultBean insultBean;
}

and

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

and

<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>
BalusC
  • 1,082,665
  • 372
  • 3,610
  • 3,555
  • Aww. Excuse me for not being precise enough with my example. I'm bound to JSF 1. I've experimented with putting bean in session scope but with the same result :( – ceggers Oct 14 '10 at 11:13
  • Thank you. So I'm doomed with JSF 1.1? – ceggers Oct 14 '10 at 11:30
0

Make the button disabled with javascript once it's clicked.

Bozho
  • 588,226
  • 146
  • 1,060
  • 1,140
  • This would work, unfortunately the real situation is a little different from my example. The redirect occurs from a third party page that is out of my control. – ceggers Oct 14 '10 at 10:13