-1

I would like to schedule sending email notifications using Spring boot, the user creates the notification(Subject, Message, Sending date...)

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;

Normally, I get a list of notifications from the DB, and I should send each notification using the loop "for" with its own informations (specified by the client), but I found a problem with the sending time, I couldn't use the @scheduled annotation because the cron expression here should be dynamic(retrieved from the DB) Here is my method:

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...
        }

    }

I started this method:

    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();
        }
    }

But I want to schedule the sending of the email at the time specified by the client, in the method above, the cron expression is static, and that's not what I'm looking for

darwin
  • 27
  • 1
  • 8

1 Answers1

1

I advice you to explore Quartz library. For the start: https://www.baeldung.com/spring-quartz-schedule. It is well integrated with Spring and provides smarter scheduling than the standard Spring implementation. It also supports persistence for your scheduled tasks.

Also here there is an example of manual job creation. So you can send emails using time and date specified by the client.

As the alternative, you can fetch all not sent emails with the current sendingDate e.g. every midnight using default Spring @Scheduled annotation, send it and mark notification as sent. But of course there would be problems in case of a few replicas of your app. So I thing using Quartz is the most mature solution.

Anton Shelenkov
  • 315
  • 4
  • 13