当前位置: 首页 > 知识库问答 >
问题:

使用Quartz和Spring boot计划任务

薛博艺
2023-03-14

我想每天使用Spring Boot发送电子邮件,用户指定发送时间,我使用石英来安排我的工作。电子邮件的收件人有(id、emailAddress、截止日期)电子邮件将发送给截止日期=今天X...(用户指定X)。例如:用户指定X是1号,所以我们对明天有截止日期的人感兴趣。

第1天:应用程序向截止日期为今天1的人发送电子邮件。。第二天:我希望应用程序在第二天将电子邮件发送给新的收件人,但使用下面的代码,电子邮件将发送给在第1天收到它的人,这不是我所需要的。

@PostMapping("/scheduleEmailPeriodic")
    public ResponseEntity<ScheduleEmailResponse> SendScheduleEmailPeriodic(
            @Valid @RequestBody PeriodicNotification scheduleEmailRequest) throws Exception {
        ens.schedulePeriodicNotification(scheduleEmailRequest);
        LocalDate localDateTime = LocalDate.now();
        LocalTime localTime = LocalTime.parse(scheduleEmailRequest.getSendingTime());

        

        try {
            ZonedDateTime dateTime = ZonedDateTime.of(localDateTime, localTime,ZoneId.of("Africa/Casablanca"));
            if (dateTime.isBefore(ZonedDateTime.now())) {
                ScheduleEmailResponse scheduleEmailResponse = new ScheduleEmailResponse(false,
                        "dateTime must be after current time");
                return ResponseEntity.badRequest().body(scheduleEmailResponse);
            }

            JobDetail jobDetail = buildPeriodicJobDetail(scheduleEmailRequest);
            Trigger trigger = buildJobTriggerPeriodic(jobDetail, dateTime);
            scheduler.scheduleJob(jobDetail, trigger);

            ScheduleEmailResponse scheduleEmailResponse = new ScheduleEmailResponse(true, jobDetail.getKey().getName(),
                    jobDetail.getKey().getGroup(), "Email Scheduled Successfully!");
            return ResponseEntity.ok(scheduleEmailResponse);
        } catch (SchedulerException ex) {
            logger.error("Error scheduling email", ex);

            ScheduleEmailResponse scheduleEmailResponse = new ScheduleEmailResponse(false,
                    "Error scheduling email. Please try later!");
            return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body(scheduleEmailResponse);
        }
    }

private JobDetail buildPeriodicJobDetail(PeriodicNotification scheduleEmailRequest) {
        JobDataMap jobDataMap = new JobDataMap();
        List<String> recipients = fileRepo.findWantedEmails(scheduleEmailRequest.getDaysNum());

        if(recipients.isEmpty()) {
            throw new RuntimeException("Aucun destinataire trouvé");
        }
        String[] to = recipients.stream().toArray(String[]::new);

        jobDataMap.put("recipients", to);
        jobDataMap.put("subject", scheduleEmailRequest.getSubject());
        jobDataMap.put("body", scheduleEmailRequest.getMessage());

        return JobBuilder.newJob(EmailJob.class).withIdentity(UUID.randomUUID().toString(), "email-jobs")
                .withDescription("Send Email Job").usingJobData(jobDataMap).storeDurably().build();
    }

    private Trigger buildJobTriggerPeriodic(JobDetail jobDetail, ZonedDateTime startAt) {
        return TriggerBuilder.newTrigger().forJob(jobDetail)
                .withIdentity(jobDetail.getKey().getName(), "email-triggers")
                .withDescription("Send Periodic Email Trigger")
                .withSchedule(SimpleScheduleBuilder
                .repeatHourlyForever(24))
                .startAt(Date.from(startAt.toInstant()))
                .build();
    }

这是电子邮件作业:

@Override
    protected void executeInternal(JobExecutionContext context) throws JobExecutionException {
        logger.info("Executing Job with key {}", context.getJobDetail().getKey());
        JobDataMap jobDataMap = context.getMergedJobDataMap();
        String subject = jobDataMap.getString("subject");
        String body = jobDataMap.getString("body");
        String[] recipients = (String[])jobDataMap.get("recipients");
        sendMail("smsender4@gmail.com", recipients, subject, body);
        
    }
    
     private void sendMail(String fromEmail, String[] toEmail, String subject, String body) {
            try {
                logger.info("Sending Email to {}", Arrays.toString(toEmail));
                MimeMessage message = mailSender.createMimeMessage();

                MimeMessageHelper messageHelper = new MimeMessageHelper(message, StandardCharsets.UTF_8.toString());
                messageHelper.setSubject(subject);
                messageHelper.setText(body, true);
                messageHelper.setFrom(fromEmail);
                messageHelper.setTo(toEmail);

                mailSender.send(message);
            } catch (MessagingException ex) {
                logger.error("Failed to send email to {}", Arrays.toString(toEmail));
            }
        }

}

我真的需要帮助,我需要每天都有新的收件人,而不是将电子邮件发送给同一个收件人。

共有1个答案

牟辰龙
2023-03-14

您发送的电子邮件是基于日期的,但您无法跟踪为特定用户发送电子邮件的时间。因此,如果您今天将向user1发送一封电子邮件,那么user1在第二天仍然处于状态。您需要添加一个标志(或一些其他逻辑),表明已为此用户发送了电子邮件

 类似资料:
  • 我有一个简单的计划任务,它是使用@计划注释创建的。类似这样的东西- 我还有一个蓝绿色升级场景,在这个场景中,这个计划任务可能会在蓝色和绿色集群中运行。鉴于这个计划任务修改了数据库,其中一个节点可能会覆盖来自另一个节点的数据——或者最坏情况下的竞争条件。 我想暂停绿色集群上所有计划的任务,直到它准备好接受流量。我已经有了代码来监听应用程序状态的变化。 我探索了几个选择- 只需在任务开始时添加一个布尔

  • 问题内容: 我是Spring-boot(版本1.3.6)和Quartz的新手,我想知道使用Spring- scheduler 进行任务之间有什么区别: 和石英方式: 在代码中: 和sheduler: Quartz是否提供了更灵活的方式来定义Jobs,Triggers和Scheduler,或者Spring Scheduler还有其他更好的方法? 问题答案: Spring Scheduler是一个抽象

  • 我用SpringBoot创建了一个简单的演示应用程序,其中包括执行器。带有@Scheduled注释的任务显示在执行器中,但以编程方式启动的任务不会显示。有没有办法让他们也出现? 我已经注释了@Enable调度。 我的组件如下所示: 执行器的结果仅显示带注释的任务:

  • Spring使用Quartz的顺序作业计划 我有三个或更多的工作,这取决于他们各自以前的工作,他们将按顺序运行。如果完成运行,当完成运行。如果在上一个中发生任何错误,则不会激发下一个触发的作业。我试图了解工作链使用石英,但无法通过它。 作业顺序如下所示 提前谢了。

  • 我正在从事一个Spring Webflux项目,在计划任务中发布和使用Flux时遇到了一个问题。 我配置的调度程序: 除非我在最后故意阻止,否则这项任务永远不会完成: 我最初没有费心直接引用发布/订阅计划程序,我尝试了所有看似合理但没有效果的选项。 我的日志事件发生了,但当来自调度程序的该任务的线程死亡时,通量也会被丢弃;即使在我指定发布和订阅行为后,它们应该在自己的线程池中? 我想使这个行动完全

  • 我在parallelism 5上有一份flink的工作(目前!!)。其中一个richFlatMap流在打开(配置参数)方法中打开一个文件。在flatMap操作中,没有任何打开操作,它只是读取文件来搜索某些内容。(有一个实用程序类,它的方法类似于utilityClass.searchText(“abc”))。以下是样板代码: python脚本每天都会在特定时间更新此文件。因此,我还应该在flatMa