我希望能够在java中执行异步任务,并能够保持与用户会话关联的完成(如果可能的话,进展)监视器。这是可能的,如果是的话,这是做什么的?
目前,该任务是作为无状态会话bean方法同步实现的,该方法是从jax-rs端点调用的。
我查看了https://docs.oracle.com/javaee/7/tutorial/ejb-async001.htm,但AsyncResult
不可序列化,所以我想我无法将其添加到会话中。
答案 0 :(得分:3)
使用Spring注释@Async,可以使任何bean /方法异步。 容器将创建一个新线程,并且方法将异步执行。您也可以将会话对象传递给此方法,并在完成后,可以在会话对象中标记属性。 示例: - https://spring.io/guides/gs/async-method/
答案 1 :(得分:0)
JSF示例,适用于Wildfly:
1 in view in view(xhtml)我们有一个上传表格和进度表
<h:form>
<div align="justify">
<p:fileUpload style="width: auto" fileUploadListener="#{fileUploadCtrl.handleFileUpload}" mode="advanced" label="Please pick XLS file" update="messages" auto="true" sizeLimit="1000000" allowTypes="/(\.|\/)(xls|xlsx)$/" />
<p:growl id="messages" showDetail="false" life="4000"/>
</div>
</h:form>
<h:form id="wholeform">
<h:outputText id="statusot" value="#{fileUploadCtrl.message}" />
<p:spacer width="10" height="10"/>
<p:poll interval="1" listener="#{fileUploadCtrl.updateStatus}" update="wholeform" />
</h:form>
2在控制器中,它是一个托管bean,我们处理文件,一次是第二次更新状态
@ManagedBean
@ViewScoped
public class FileUploadCtrl {
@EJB
private SomeBusinessLogicClass model;
@EJB
private ProgressTracker progress;
private Future<List<String>> asyncResult;
private int progressId = 0;
private String message;
private boolean busy = false;
public void handleFileUpload(FileUploadEvent event) {
Set<String> ids = model.populate(event.getFile().getContents());
progressId = progress.newIndex();
asyncResult = model.process(ids);
busy = true;
FacesMessage message = new FacesMessage("Loaded " + ids.size() + " objects", "");
FacesContext.getCurrentInstance().addMessage(null, message);
}
public void updateStatus() {
if (!busy)
return;
try {
if (asyncResult.isDone()) {
List<String> r = asyncResult.get();
message = "Job done";
busy = false;
progress.delIndex(progressId);
} else {
message = progress.getIndex(progressId)+"-th element in work";
}
} catch (Exception e) {
System.out.println("updateStatus " + e.toString());
}
}
3所有业务逻辑都在EJB中,如SomeBusinessLogicClass或许多其他逻辑。我们还需要一个简单的进度管理器EJB,我完全发布它
@Singleton
public class ProgressTracker {
private Map<Integer,Integer> indexes = new HashMap<>();
public Map<Integer, Integer> getIndexes() {
return indexes;
}
public void setIndexes(Map<Integer, Integer> indexes) {
this.indexes = indexes;
}
public Integer newIndex() {
Integer size = indexes.size();
indexes.put(size,0);
return size;
}
public void incIndex(final Integer index) {
int old = indexes.get(index);
old++;
indexes.put(index,old);
}
public Integer getIndex(final Integer index) {
return indexes.get(index);
}
public void delIndex(Integer index) {
indexes.remove(index);
}
}
也许这个例子并不优雅,我几乎是前端的新手,但它比没有任何东西更有效。