How to prevent a request scoped bean method being called multiple times in a JSF application?
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) w开发者_如何学JAVAebapp I have a request scoped bean bean
of class Bean
. When the user quickly clicks a commandButton
multiple times to redirect him to the insult.xhtml
page the doSomethingThatTakesALittleLongerAndShouldOnlyBeDoneOnce
method 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>
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>
Make the button disabled with javascript once it's clicked.
精彩评论