@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();
}
}
登录后的用户数据存储在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();
}
}