gpt4 book ai didi

java - 公开要在 View 中使用的 @Asynchronous 函数的当前进度

转载 作者:行者123 更新时间:2023-11-29 04:01:22 25 4
gpt4 key购买 nike

在我的 JEE6 应用程序(在 Glassfish 3.0.1 上运行)中,我有一个必须发送大量邮件的 EmailEJB。邮件是异步发送的,所以它用新的 EJB3.1 @Asynchronous 注释,让它在一个单独的线程中运行。现在我想让用户知道该方法的当前状态:已经发送了多少封邮件?

异步发送邮件工作正常,但我不知道如何让进度可以从外部访问。似乎我这样做的方法是完全错误的,但不知何故它必须是可能的(也许是另一种方法)。这就是我的 EmailEJB 当前的样子(它是一种伪代码,但解释了我想要的):

@Stateful
public class EmailEJB {

@Asynchronous
public Future<Integer> sendMails() {
for (int i=0; i<mails.size; i++) {
sendMail(mails[i])
// i want to return the progress without returning ;)
return new AsyncResult<Integer>(i)
}
}
}

//Just for the completeness... from outside, i'm accessing the progress like this:
Future<Integer> progress = emailEJB.sendEmails();
Integer currentvalue = progress.get();

如何在我的异步函数中返回当前进度,而不用返回取消它?我如何向用户显示函数内循环的进度?我需要另一种异步方法吗?有什么提示吗?

最佳答案

没有人吗?好的,这是我的解决方案。我不确定这是一个很大的解决方法还是只是完成此操作的一种方法。

由于@Asynchronous 方法无法访问 session 上下文,因此也没有 session Bean(至少我不知道如何,我总是遇到 ConcurrentModificationErrors 或类似错误)我创建了一个 Singleton ProgressEJB,其中包含一个 HashMap:

@Singleton @LocalBean @Startup
public class ProgressEJB {
private HashMap<String, Integer> progressMap = new HashMap<String, Integer>
// getters and setters
}

此 HashMap 应将 SessionId(一个字符串)映射到一个整数值(进度 0->100)。因此,用户 session 与进度相关联。在我的 EmailEJB 中,我注入(inject)了这个 ProgressEJB,并且在我的@Asynchronous 方法中,每次发送电子邮件时我都会增加该值:

@Stateful @LocalBean
public class EmailEJB {
@Inject
private ProgressEJB progress;
// Mail-Settings
...
@Asynchronous
public void sendEmails(user:User, message:Message, sessionId:String) {
progress.progressMap.put(sessionId, 0);
for (int i=0; i<mails.size; i++) {
sendMail(mails[i])
progress.getProgressMap().put(sessionId, (i / mails.size) * 100)
}
progress.getProgressMap().remove(sessionId);
}

调用函数时,sessionId 来 self 的托管(焊接)Bean:

@SessionScoped
@Named
public class EmailManager {
@Inject
private ProgressEJB progress;
@Inject
private FacesContext facesContext;

private String sessionId;

@PostConstruct
private void setSessionId() {
this.sessionId = ((HttpSession)facesContext.getExternalContext().getSession(false)).getId();
}

public Integer getProgress() {
if (progress.getProgressMap().get(sessionId) == null)
return 100;
else
return progress.getProgressMap().get(sessionId);
}
}

现在我可以使用 Ajax 轮询从我的 JSF View 访问 EmailManager 的进度,告诉用户已经发送了多少封邮件。刚刚对 2 位用户进行了测试,似乎有效。

关于java - 公开要在 View 中使用的 @Asynchronous 函数的当前进度,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3355336/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com