Как предотвратить многократный вызов метода bean-компонента с областью запроса в приложении JSF?

Хорошо, со всеми ответами на этот вопросЯ все еще не могу справиться со своей проблемой. У меня есть следующее созвездие:

В веб-приложении JSF (1.1) у меня есть bean-компонент с областью запроса beanof class 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();
}

оскорбление.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>

person ceggers    schedule 14.10.2010    source источник


Ответы (2)


Сделайте сеанс bean-компонента ограниченным и аннотируйте метод с помощью @PostConstruct. Если вы настаиваете на том, чтобы его область действия была ограничена запросом, разделите эту часть на bean-компонент с областью действия сеанса и сделайте ее управляемым свойством bean-компонента с областью действия запроса, используя @ManagedProperty.

@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>
person BalusC    schedule 14.10.2010
comment
Ой. Извините, что я недостаточно точен в своем примере. Я привязан к JSF 1. Я экспериментировал с помещением компонента в область сеанса, но с тем же результатом :( - person ceggers; 14.10.2010
comment
Спасибо. Так что я обречен с JSF 1.1? - person ceggers; 14.10.2010

Сделайте кнопку отключенной с помощью javascript после нажатия.

person Bozho    schedule 14.10.2010
comment
Это сработает, к сожалению, реальная ситуация немного отличается от моего примера. Перенаправление происходит со сторонней страницы, которая находится вне моего контроля. - person ceggers; 14.10.2010