我使用Java(Servlet,JSP)开发Web应用程序。
我有一个发送电子邮件的课程。
类看起来像:
public class EmailSender
{
String SendEmail(String from,Session session,String To,String CC, String BCC, String Subject,String Body)
{
//Actual code for sending emails
}
}
从另一个类调用 EmailSender
类:
public class InvokeSender
{
public InvokeSender(String dbFileName)
{
//get emails from database for sending who has STATUS='NOTSENT'
//statements to get all required parameter to pass to SendEmail()
EmailSender sender = new EmailSender();
String msg = sender.SendEmail(fromEmail,session,To,CC,BCC,SUBJECT,BODY);
}
}
当用户点击按钮时,将从servlet调用InvokeSender
。
当用户点击按钮时,会调用InvokeSender,它会从数据库发送电子邮件并形成它们,然后将这些参数传递给SendEmail()
类的EmailSender
。
我希望一次只运行一个InvokeSender
个实例,以避免在按两次按钮时同一封电子邮件发送两次。如何处理?在这种情况下,multithreading
会有用吗?
任何建议都将受到赞赏。
UPDATE1 用户点击后我无法禁用该按钮。因为如果用户刷新页面,那么默认情况下将启用该按钮。
UPDATE2
第一个用户选择客户,模板等发送电子邮件,然后将电子邮件参数存储在数据库中。 InvokeSender
课程会收到要发送的所有电子邮件。无法预测要发送的电子邮件数。它可以是1或500或更多。我只希望运行InvokeSender
的一个实例,直到上一个实例完成发送电子邮件。功能(生成和发送电子邮件的按钮)将向5-7个用户公开。
答案 0 :(得分:2)
我认为,可以通过创建一个具有会话范围的唯一令牌来完成,该页面具有电子邮件发件人和Servlet类中的Singleton Map以维护令牌。
创建servlet过滤器以生成页面的会话范围标记。
如果地图中不存在令牌,则将令牌添加到 映射并调用邮件发件人。
如果包含,则不要调用邮件 发送方
答案 1 :(得分:1)
您可以使用队列数据结构对发送电子邮件请求进行排队,并在单独的线程中处理它们。该线程将在启动期间生成一次并将处理队列。发送电子邮件后,STATUS='NOTSENT'
将被清除,这将解决多个电子邮件问题。队列可以定期处理,也可以轮询数据,或者有一些信号机制在队列中有数据时发出信号。
修改:我认为此解决方案适合 Update1 和 Update2
答案 2 :(得分:1)
我会在InvokeSender中使用AtomicBoolean然后执行此操作:
public class InvokeSender
{
static AtomicBoolean sendInProgress = new AtomicBoolean(false);
public InvokeSender(String dbFileName)
{
if (sendInProgress.compareAndSet(false, true)) {
//get emails from database for sending who has STATUS='NOTSENT'
//statements to get all required parameter to pass to SendEmail()
EmailSender sender = new EmailSender();
String msg = sender.SendEmail(fromEmail,session,To,CC,BCC,SUBJECT,BODY);
sendInProgress.set(false);
}
}
}
当然,这是一个非常简单的解决方案,如果您想要更复杂的行为,例如限制上一封电子邮件和下一封电子邮件之间的时间,您将不得不为此添加更多逻辑。
答案 3 :(得分:1)
使用synchronized块
public InvokeSender(String dbFileName)
{
synchronized(InvokeSender.class){
//get emails from database for sending who has STATUS='NOTSENT'
//statements to get all required parameter to pass to SendEmail()
EmailSender sender = new EmailSender();
String msg = sender.SendEmail(fromEmail,session,To,CC,BCC,SUBJECT,BODY);
}
}