首页 > 解决方案 > 在 Spring Boot 中安排发送电子邮件

问题描述

我想安排使用 Spring Boot 发送电子邮件通知,用户创建通知(主题、消息、发送日期...)

public class EmailNotification implements Serializable {
    
    /**
     * 
     */
    private static final long serialVersionUID = 3400952201530474821L;
    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    private long id;
    private String subject;
    private String message;
    @Column(name = "sending_date")
    @Basic(fetch = FetchType.EAGER)
    private String sendingDate;

通常,我从数据库中获取通知列表,我应该使用循环“for”发送每个通知及其自己的信息(由客户端指定),但我发现发送时间有问题,我无法使用@scheduled 注释,因为这里的 cron 表达式应该是动态的(从数据库中检索)这是我的方法:

public void periodicNotification()  {
        JavaMailSenderImpl jms = (JavaMailSenderImpl) sender;
        MimeMessage message = jms.createMimeMessage();
        MimeMessageHelper helper;
        try {
            helper = new MimeMessageHelper(message, MimeMessageHelper.MULTIPART_MODE_MIXED_RELATED, StandardCharsets.UTF_8.name());
            
        //get the list of notifs from the DB
        List<EmailNotification> emailNotifs = emailNotificationsRepo.findAll();

        for (EmailNotification i : emailNotifs) 
        {
            helper.setFrom("mail");
            List<String> recipients = fileRepo.findWantedEmails(i.getDaysNum());

            String[] to = recipients.stream().toArray(String[]::new);
            helper.setTo(to);
            helper.setText(i.getMessage());
            helper.setSubject(i.getSubject());
            sender.send(message);
            System.out.println("Email successfully sent to: " + Arrays.toString(to));
        }
        }
        catch (MessagingException e) {
            
            e.print...
        }

    }

我开始了这个方法:

    public static void main(String[] args) {
        try {
            JobDetail job1 = JobBuilder.newJob(Job1.class).withIdentity("job1", "group1").build();

            Trigger trigger1 = TriggerBuilder.newTrigger().withIdentity("cronTrigger1", "group1")
                    .withSchedule(CronScheduleBuilder.cronSchedule("0/30 * * * * ?")).build();

            Scheduler scheduler1 = new StdSchedulerFactory().getScheduler();
            scheduler1.start();
            scheduler1.scheduleJob(job1, trigger1);

            Thread.sleep(100000);

            scheduler1.shutdown();

        } catch (Exception e) {
            e.printStackTrace();
        }
    }

但我想安排在客户端指定的时间发送电子邮件,在上面的方法中,cron 表达式是静态的,这不是我要找的

标签: springspring-bootcronjobsschedule

解决方案


我建议您探索Quartz库。首先:https ://www.baeldung.com/spring-quartz-schedule 。它与 Spring 很好地集成,并提供比标准 Spring 实现更智能的调度。它还支持您的计划任务的持久性。

这里还有一个手动创建作业的示例。因此,您可以使用客户指定的时间和日期发送电子邮件。

作为替代方案,您可以使用默认的 Spring @Scheduled 注释获取所有当前正在发送的未发送电子邮件,例如每个午夜,发送它并将通知标记为已发送。但是,如果您的应用程序有几个副本,当然会出现问题。所以我认为使用 Quartz 是最成熟的解决方案。


推荐阅读