Jsf 全局设置CDI会话超时

Jsf 全局设置CDI会话超时,jsf,weblogic,cdi,weld,Jsf,Weblogic,Cdi,Weld,是否可以为注入@Named bean的所有对话对象全局设置对话超时 我有几个@ConversationScope bean,例如: import javax.annotation.PostConstruct; import javax.enterprise.context.Conversation; import javax.enterprise.context.ConversationScoped; import javax.inject.Inject; import javax.inject

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

我有几个@ConversationScope 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,在每个CDI bean中手动设置超时不是最好的解决方案)

对于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) {

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

import org.jboss.weld.context.http.HttpConversationContext;
导入javax.inject.inject;
导入javax.servlet.annotation.WebListener;
导入javax.servlet.http.HttpSessionEvent;
导入javax.servlet.http.HttpSessionListener;
@网络监听器
公共类SessionListener实现了HttpSessionListener{
@注入
私有HttpConversationContext会话上下文;
@凌驾
已创建公共无效会话(HttpSessionEvent HttpSessionEvent){
if(conversationContext!=null){
最终长默认_超时=2*60*60*1000;
if(conversationContext.getDefaultTimeout()

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

这可以通过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
    }

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


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

if (conversation.isTransient()) {
        conversation.setTimeout(((HttpServletRequest)FacesContext.getCurrentInstance().getExternalContext()
                .getRequest()).getSession().getMaxInactiveInterval()*1000);
        conversation.begin();
    }

感谢您的提示,以同样的方式实现了这一点,现在将发布解决方案:)什么是
prelocompleteevent
?在(Weld 2.x)文档中找不到关于它的任何信息。因此,我使用了一个类似的观察者方法:
public void observeAppInit(@obsers@Initialized(ApplicationScoped.class)Object event)
并在该方法内执行工作,该方法按照建议工作。preload completeevent是一个自定义事件,要使用默认值,您还可以执行
public void observepload(@Observes@Started WebApplication webapp){
或者你的建议正如下面的一些答案所展示的,没有一个标准的方法来做这件事。你做的任何事情(除了stasal的答案)不是可移植的。我认为您应该列出导入以便更好地理解。javax.enterprise.context.Initialized是java ee api 7的一部分,但是我们,例如,使用java ee 6,所以唯一的方法是依赖jboss cdi api,它比我的解决方案更具可移植性,但仍然不是100%Iguess@stasal,是的,CDI 1.1实际上是必需的我修改了我的答案。什么时候调用sessionCreated?这个类应该在web.xml中配置吗?当创建新的客户端会话时调用sessionCreated方法。这个类应该在web.xml描述符中配置,或者像上面的代码示例中那样进行注释(但是“元数据已完成”web.xml中的属性应省略或等于“false”)。有关hadling servlet生命周期事件的更多信息,请参见:
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();
    }

}
if (conversation.isTransient()) {
        conversation.setTimeout(((HttpServletRequest)FacesContext.getCurrentInstance().getExternalContext()
                .getRequest()).getSession().getMaxInactiveInterval()*1000);
        conversation.begin();
    }