2010-10-14 27 views
1

Ok, avec toutes les réponses à this question Je ne suis toujours pas capable de gérer mon problème. J'ai la constellation suivante:Comment éviter qu'une méthode de demande de beans portée soit appelée plusieurs fois dans une application JSF?

Dans une webapp JSF (1.1), j'ai une demande haricot sciée bean de la classe Bean. Lorsque l'utilisateur clique rapidement sur un commandButton plusieurs fois pour le rediriger vers la page insult.xhtml, la méthode doSomethingThatTakesALittleLongerAndShouldOnlyBeDoneOnce peut être invoquée plusieurs fois (sur Tomcat 6). Comment puis-je empêcher cela?

... 
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> 

Répondre

0

Faire le bouton désactivé javascript avec une fois qu'il a cliqué.

+0

Cela fonctionnerait, malheureusement, la situation réelle est un peu différent de mon exemple. La redirection provient d'une page tierce qui est hors de mon contrôle. – ceggers

2

Rend la portée de la session du bean et annote la méthode avec @PostConstruct. Si vous insistez pour conserver la portée de la demande, divisez cette partie en une bean de portée de session et faites-en une propriété gérée du bean de portée de requête en utilisant @ManagedProperty.

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

et

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

Alors JSF prendra soin qu'il a créé et appelé une seule fois au cours de la session.


Mise à jour: désolé, vous utilisez JSF 1.x. Si elle est de 1,2, alors ce qui suit donne le même:

public class Bean { 
    private InsultBean insultBean; 
} 

et

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

et

<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> 
+0

Aww. Excusez-moi de ne pas être assez précis avec mon exemple. Je suis lié à JSF 1. J'ai expérimenté avec mettre le bean dans la portée de la session mais avec le même résultat :( – ceggers

+0

Voir la réponse à la question – BalusC

+0

Merci, donc je suis condamné avec JSF 1.1? – ceggers