6

是否可以为注入 @Named bean 的所有对话对象全局设置对话超时?

我有几个 @ConversationScoped bean,例如:

import javax.annotation.PostConstruct;
import javax.enterprise.context.Conversation;
import javax.enterprise.context.ConversationScoped;
import javax.inject.Inject;
import javax.inject.Named;

@Named
@ConversationScoped
public class SomeBean1 {

    @Inject
    private Conversation conversation;

    @PostConstruct
    private void init() {
        if (conversation.isTransient()) {
            conversation.begin();
        }
    }
}

@Named
@ConversationScoped
public class SomeBean2 {

    @Inject
    private Conversation conversation;

    @PostConstruct
    private void init() {
        if (conversation.isTransient()) {
            conversation.begin();
        }
    }
}        

这些对话的默认超时为 600000 毫秒。我想知道是否有任何方法可以全局设置对话超时,或者我需要在每个 bean 中设置它

if (!conversation.isTrainsient()) {
    conversation.setTimeout(MY_CUSTOM_TIMEOUT);
}

(问题是有很多 CDI bean 并且在每个中手动设置超时不是最好的解决方案)

4

4 回答 4

2

所以,这是我使用的解决方案(Oracle WebLogic 12c,WELD 1.1.Final):

import org.jboss.weld.context.http.HttpConversationContext;

import javax.inject.Inject;
import javax.servlet.annotation.WebListener;
import javax.servlet.http.HttpSessionEvent;
import javax.servlet.http.HttpSessionListener;

@WebListener
public class SessionListener implements HttpSessionListener {

    @Inject
    private HttpConversationContext conversationContext;

    @Override
    public void sessionCreated(HttpSessionEvent httpSessionEvent) {
        if (conversationContext != null) {
            final long DEFAULT_TIMEOUT = 2 * 60 * 60 * 1000;
            if (conversationContext.getDefaultTimeout() < DEFAULT_TIMEOUT){
                conversationContext.setDefaultTimeout(DEFAULT_TIMEOUT);
            }
        }
    }

    @Override
    public void sessionDestroyed(HttpSessionEvent httpSessionEvent) {}
}

上下文被注入到侦听器中,并在用户启动会话时设置超时。

于 2013-10-01T17:59:56.260 回答
2

使用 Seam/Weld,您应该能够执行以下操作:

@Inject
private HttpConversationContext conversationContext;

public void observePreload(@Observes PreloadCompleteEvent event) {
    //Set global conversation timout to 60000 ms
    conversationContext.setDefaultTimeout(60000);
}

否则我相信你将不得不为每次对话设置它。

编辑:注意我使用了一个自定义事件,同样可以通过以下方式完成:

public void observePreload(@Observes @Started WebApplication webapp) {
于 2013-10-01T15:05:31.987 回答
1

这可以通过 CDI 1.1 以可移植的方式轻松完成。

import javax.enterprise.context.Conversation;
import javax.enterprise.context.ConversationScoped;
import javax.enterprise.context.Initialized;
import javax.enterprise.event.Observes;
import javax.inject.Inject;
import javax.servlet.ServletRequest;

public class ConversationTimeoutDefaultSetter {

    @Inject
    private Conversation conversation;

    public void conversationInitialized(
            @Observes @Initialized(ConversationScoped.class)
            ServletRequest payload) {
        conversation.setTimeout(1800000L); // 30 minutes
    }

}

另一种便携式选择是装饰对话。(警告:未经测试。)

import static javax.interceptor.Interceptor.Priority.APPLICATION;

import javax.annotation.Priority;
import javax.decorator.Decorator;
import javax.decorator.Delegate;
import javax.enterprise.context.Conversation;
import javax.inject.Inject;

@Decorator
@Priority(APPLICATION)
public class ConversationTimeoutDefaultSetter implements Conversation, Serializable {

    private static final long serialVersionUID = 1L;

    @Inject
    @Delegate
    private Conversation delegate;

    private void setDefaultTimeout() {
        delegate.setTimeout(1800000L); // 30 minutes
    }

    @Override
    public void begin() {
        setDefaultTimeout();
        delegate.begin();
    }

    @Override
    public void begin(String id) {
        setDefaultTimeout();
        delegate.begin(id);
    }

    @Override
    public void end() {
        delegate.end();
    }

    @Override
    public String getId() {
        return delegate.getId();
    }

    @Override
    public long getTimeout() {
        return delegate.getTimeout();
    }

    @Override
    public void setTimeout(long milliseconds) {
        delegate.setTimeout(milliseconds);
    }

    @Override
    public boolean isTransient() {
        return delegate.isTransient();
    }

}
于 2014-08-08T17:27:39.480 回答
0

您还可以将会话 bean 的超时时间与当前 http 请求的会话超时时间同步:

if (conversation.isTransient()) {
        conversation.setTimeout(((HttpServletRequest)FacesContext.getCurrentInstance().getExternalContext()
                .getRequest()).getSession().getMaxInactiveInterval()*1000);
        conversation.begin();
    }
于 2016-09-22T09:02:42.443 回答