@Schedule 无法从@SessionScoped CDI bean 获取数据

@Schedule could not fetch data from @SessionScoped CDI bean

登录后的用户数据存储在SessionScoped bean中。 我想每 5 秒将每个帐户存储在会话中并发送到后端。 我的计时器

@Singleton
@Startup
public class FrontendTimer {

    @Inject
    private UserContext userContext;

    @Schedule(second = "*/5", minute = "*", hour = "*", persistent = false)
    @Asynchronous
    public void atSchedule() throws InterruptedException {
        System.out.println("Get Logged user stored in the session each 5 seconds ");
        System.out.println("FR " + userContext.getAccount().toString());
    }

}

启动调度程序的唯一方法是创建@Startup 和@Singleton class。 将用户数据保存在前端的唯一方法,将帐户保存到 SessionScoped CDI bean,不推荐使用 JSF 本机 bean。

您将收到如下错误: WELD-001303:范围类型 javax.enterprise.context.SessionScoped

没有活动上下文

项目位置在这里https://github.com/armdev/eap Class 本身 https://github.com/armdev/eap/blob/master/eap-web/src/main/java/io/project/app/beans/FrontendTimer.java

基本上我想要一个可以从会话范围获取数据的标准计时器。

您当前的方法不会像您预期的那样工作,因为每个调度程序调用都将在与会话完全隔离的上下文中发生(因此 No active contexts... 错误消息)。

我建议你在这里使用一个简单的反转。在你的应用程序范围的单例中,添加一个简单的 List<String> currentSessions 和相应的方法到 void add(String account)void remove(String account)。然后 @Inject 单例进入会话范围的 bean(而不是相反)。最后,添加一个@WebListener来处理session事件。

@Singleton
public class SessionManager {

    private List<String> currentSessions;

    @Schedule(second = "*/5", minute = "*", hour = "*", persistent = false)
    @Asynchronous
    public void atSchedule() throws InterruptedException {
        //Do something with currentSessions
    }

    public void add(String account){
        currentSessions.add(account);
    }

    public void remove(String account){
        currentSessions.remove(account);
    }

}
@SessionScoped
public class UserContext implements Serializable {

    @Inject
    private SessionManager sessionManager;

    /*
    ...
    */

    public void sessionCreated(){
        sessionManager.add(account.toString());
    }

    public void sessionDestroyed(){
        sessionManager.remove(account.toString());
    }

}
@WebListener
    public class SessionListener implements HttpSessionListener {

        @Override
        public void sessionCreated(HttpSessionEvent se) {
            HttpSession session = se.getSession();

            FacesContext context = FacesContext.getCurrentInstance();
            UserContext userContext = (UserContext) session.getAttribute("userContext");
            userContext.sessionCreated();
        }

        @Override
        public void sessionDestroyed(HttpSessionEvent se) {
            HttpSession session = se.getSession();

            FacesContext context = FacesContext.getCurrentInstance();
            UserContext userContext = (UserContext) session.getAttribute("userContext");
            userContext.sessionDestroyed();

        } 
    }