如何每天在特定时间使用Java发送邮件

时间:2019-05-14 06:31:39

标签: java tomcat scheduled-tasks javamail

我正在使用JavaservletsJSP的web_application应用程序,并使用apache Tomcat作为应用程序服务器

我做了什么

  • 我已经创建了一个UI,用户可以在其中选择邮件ID(他们可以选择多个ID)
  • 当用户单击“发送”按钮时,我会触发我的java类并发送邮件

现在我该怎么办

  • 现在,我必须动态地执行此操作,每天晚上12:00,我必须向某些特定用户发送邮件

  • 我必须向其发送邮件的用户我正在从登录查询中获取该邮件ID,所以这不是问题

  • 我只想知道在午夜12:00时如何发送邮件

我到目前为止所做的填充

servlet类

public class EmailSendingServlet extends HttpServlet {

private static final long serialVersionUID = 1L;
private String host;
private String port;
private String user;
private String pass;

public void init() {

    ServletContext context = getServletContext();
    host = context.getInitParameter("host");
    port = context.getInitParameter("port");
    user = context.getInitParameter("user");
    pass = context.getInitParameter("pass");
}

protected void doPost(HttpServletRequest request,
        HttpServletResponse response) throws ServletException, IOException {
    String recipient = request.getParameter("To"); // this i will get from login query
    String subject = request.getParameter("subject");//this i can define manually
    String content = request.getParameter("content");//same for this also


    String resultMessage = "";

    try {
        EmailUtility.sendEmail(host, port, user, pass, recipient, subject,
                content);
        resultMessage = "The e-mail was sent successfully";
    } catch (Exception ex) {
        ex.printStackTrace();
        resultMessage = "There were an error: " + ex.getMessage();
    } 
}

}

Java Utility类

public class EmailUtility {
public static void sendEmail(String host, String port, final String userName, final String password,
        String toAddress, String subject, String message) throws AddressException, MessagingException {


    Properties properties = new Properties();
    properties.put("mail.smtp.host", host);
    properties.put("mail.smtp.port", port);
    properties.put("mail.smtp.auth", "true");
    properties.put("mail.smtp.starttls.enable", "true");
    Session session = Session.getDefaultInstance(properties, new javax.mail.Authenticator() {
        protected PasswordAuthentication getPasswordAuthentication() {
            return new PasswordAuthentication(userName, password);
        }
    });
    session.setDebug(false);
    Message msg = new MimeMessage(session);

    msg.setFrom(new InternetAddress(userName));
    if (toAddress!= null) {
        List<String> emails = new ArrayList<>();
        if (toAddress.contains(",")) {
            emails.addAll(Arrays.asList(toAddress.split(",")));
        } else {
            emails.add(toAddress);
        }
        Address[] to = new Address[emails.size()];
        int counter = 0;
        for(String email : emails) {
            to[counter] = new InternetAddress(email.trim());
            counter++;
        }
        msg.setRecipients(Message.RecipientType.TO, to);
    }
    msg.setSubject(subject);
    msg.setSentDate(new Date());
    msg.setText(message);

    Transport.send(msg);

}

}

3 个答案:

答案 0 :(得分:0)

在Java中,调度程序用于调度线程或任务,该线程或任务在特定时间段内或以固定间隔定期执行。用Java安排任务有多种方法:

  • java.util.TimerTask
  • java.util.concurrent.ScheduledExecutorService
  • Quartz Scheduler
  • org.springframework.scheduling.TaskScheduler

对于不使用任何框架的纯 java 实现,请使用ScheduledExecutorService在特定时段运行任务:

public void givenUsingExecutorService_whenSchedulingRepeatedTask_thenCorrect() 
  throws InterruptedException {
    TimerTask repeatedTask = new TimerTask() {
        public void run() {
        EmailUtility.sendEmail(host, port, user, pass, recipient,object,content);
        System.out.println("The e-mail was sent successfully");
    }
};

ZonedDateTime now = ZonedDateTime.now(ZoneId.of("America/Los_Angeles"));
ZonedDateTime nextRun = now.withHour(5).withMinute(0).withSecond(0);
if(now.compareTo(nextRun) > 0)
  nextRun = nextRun.plusDays(1);
Duration duration = Duration.between(now, nextRun);
long initalDelay = duration.getSeconds();

ScheduledExecutorService executor = Executors.newSingleThreadScheduledExecutor();
scheduler.scheduleAtFixedRate(repeatedTask,
initalDelay,
TimeUnit.DAYS.toSeconds(1),
TimeUnit.SECONDS);
executor.shutdown();
}

答案 1 :(得分:0)

您可以使用ScheduledExecutorService在“普通” Java中处理此问题:

 ScheduledExecutorService ses = Executors.newScheduledThreadPool(1);
 int count = 0;

        Runnable task = () -> {
            count++;
            System.out.println(count);
        };

        ScheduledFuture<?> scheduledFuture = ses.scheduleAtFixedRate(task, 12, TimeUnit.HOURS);

还有一种使用初始延迟的方法,但是您可以在此处阅读更多内容: https://docs.oracle.com/javase/7/docs/api/java/util/concurrent/ScheduledExecutorService.html

对于您的用例:

引入一个新的类EmailSendJobUtil

public class EmailSendUtil {
  public void createAndSubmitSheduledJob() {
   ScheduledExecutorService ses = Executors.sheduledThreadPool(1);
   ScheduledFuture<> sheduledFuture = ses.sheduleAtFixedRate(EmailUtility.sendMail(), 12, TimeUnit.HOURS);
  }
}

但是,您将在代码结构方面遇到麻烦。尝试在您的EmailUtility中引入一种方法来封装自动发送的邮件。

引入一个用于保存的存储库,您必须自动向这些用户发送邮件,并以仅处理自动发送的新方法读取此数据。您可以执行以下操作:

public class MailJobRepository {
  private List<MailJob> jobs;

  void add();
  void remove();
  List<> getJobs();
}

然后在您的EmailUtility中引入一种新方法:

public void sendAutomatedEmails() {
  jobRepository.getJobs().foreach(job -> {
   sendMail(job.getToAddress(), job.getSubject(), job.getMessage());
  });
}

然后,您可以放弃这种新方法,并且已将代码分为逻辑上独立的部分。

只是一点提示:

String host, String port, final String userName, final String password  

这是电子邮件“发送方”的数据,不应作为方法参数传递。您可以将该数据保存到EmailUtility类中。

答案 2 :(得分:0)

您应该看看isocline的Clockwork,它是一个Java流程引擎。它比Quartz能够更有效地编码各种功能,并且具有特定的执行功能。