我有CDI事件来通知我的JSF应用程序EJB进程的进度。当一切都是同步时,代码工作正常。
@Stateless
public class MySessionBean implements Serializable {
@Inject
@ProcessEvent
Event<ProcessEvent> processEvent; // Also tried to use BeanManager
@Asynchronous // This annotation breaks my code
public void runLongProcess() {
processEvent.fire(new ProcessEvent());
}
}
@Named
@ViewScoped
public class ManagedBean implements Serializable {
@EJB
MySessionBean sessionBean;
public void runProcess () {
sessionBean.runLongProcess();
}
@Asynchronous // This annotation doesn't work
public void onEvent(@Observes @ProcessEvent ProcessEvent event){
LOGGER.log(Level.INFO, "Event was received"); // Never called
}
}
如果我在@Asychronous
上使用runLongProcess()
注释,则永远不会调用JSF @Observer
方法。
如何实现此功能?
JSF 2.2 Glassfish 3.1 JEE 7 Java 8 Omnifaces 2.3
答案 0 :(得分:4)
在那个时刻和该线程中,任何地方都不一定有HTTP请求。因此,当时不一定有可用/可识别的JSF视图(更不用说HTTP请求或会话)。
它将在应用程序作用域中运行。
鉴于您正在使用OmniFaces 2.3,可能值得花些时间查看<o:socket>
以解决您的需求。它的文档也描述了这种情况以及如何在回调的帮助下正确解决它(并通过Web套接字将结果推送到视图中)。
@Inject
private SomeService someService;
@Inject @Push
private PushContext someChannel;
public void someAction() {
someService.someAsyncServiceMethod(entity, message -> someChannel.send(message));
}
@Asynchronous
public void someAsyncServiceMethod(Entity entity, Consumer<Object> callback) {
// ... (some long process)
callback.accept(entity.getSomeProperty());
}