zoukankan      html  css  js  c++  java
  • springboot+quartz实现定时任务发送邮件demo

    项目结构:

     一:实现发送邮件功能

      1:pom.xml文件  
    <?xml version="1.0" encoding="UTF-8"?>
    <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
             xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
        <modelVersion>4.0.0</modelVersion>
        <parent>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-parent</artifactId>
            <version>2.3.0.RELEASE</version>
            <relativePath/> <!-- lookup parent from repository -->
        </parent>
        <groupId>com.example.quartz</groupId>
        <artifactId>demo</artifactId>
        <version>0.0.1-SNAPSHOT</version>
        <name>demo</name>
        <description>Demo project for Spring Boot</description>
    
        <properties>
            <java.version>1.8</java.version>
        </properties>
    
        <dependencies>
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-starter-web</artifactId>
            </dependency>
            <dependency>
                <groupId>org.apache.commons</groupId>
                <artifactId>commons-pool2</artifactId>
            </dependency>
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-starter-test</artifactId>
                <scope>test</scope>
                <exclusions>
                    <exclusion>
                        <groupId>org.junit.vintage</groupId>
                        <artifactId>junit-vintage-engine</artifactId>
                    </exclusion>
                </exclusions>
            </dependency>
    
            <!-- freemarker模版 -->
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-starter-freemarker</artifactId>
            </dependency>
    
            <dependency>
                <groupId>net.sourceforge.nekohtml</groupId>
                <artifactId>nekohtml</artifactId>
            </dependency>
            <!-- email -->
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-starter-mail</artifactId>
            </dependency>
            <dependency>
                <groupId>net.sf.json-lib</groupId>
                <artifactId>json-lib</artifactId>
                <version>2.4</version>
                <classifier>jdk15</classifier><!--指定jdk版本-->
            </dependency>
            <!--quartz定时调度依赖-->
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-starter-quartz</artifactId>
            </dependency>
    
    
        </dependencies>
    
        <build>
            <plugins>
                <plugin>
                    <groupId>org.springframework.boot</groupId>
                    <artifactId>spring-boot-maven-plugin</artifactId>
                </plugin>
            </plugins>
        </build>
    
    </project>
    pom.xml
      2:配置文件
    server.path=http://localhost:8080
    server.servlet.context-path=/
    server.port=8080
    
    
    spring.mail.host=smtp.qq.com
    spring.mail.username=137846575@qq.com
    #授权码需要填写自己的
    spring.mail.password=xxx
    spring.mail.properties.mail.smtp.auth=true
    spring.mail.properties.smtp.starttls.enable=true
    spring.mail.properties.smtp.starttls.required = true
    spring.mail.default-encoding=UTF-8
    #使用freemarker模板发送
    #放置模板的位置
    spring.freemarker.template-loader-path=classpath:/static/template/
    spring.freemarker.suffix=.flt
    spring.freemarker.enabled=true
    spring.freemarker.cache=false
    spring.freemarker.charset=UTF-8
    spring.freemarker.content-type=text/html
    spring.freemarker.allow-request-override=false
    spring.freemarker.check-template-location=true
    spring.freemarker.expose-request-attributes=false
    spring.freemarker.expose-session-attributes= false
    spring.freemarker.expose-spring-macro-helpers=false
    application.yml
      3:Email实体类
    import java.io.Serializable;
    import java.util.Arrays;
    import java.util.HashMap;
    
    public class Email  implements Serializable {
    
        private static final long serialVersionUID = 1L;
        private String[] email; //接受方邮箱
        private String subject; //主题
        private String content; //内容
        private String template; //模板
    
    
    
        public Email() {
            super();
        }
    
        public Email(String[] email, String subject, String content, String template) {
            this.email = email;
            this.subject = subject;
            this.content = content;
            this.template = template;
    
        }
    
        public String[] getEmail() {
            return email;
        }
    
        public void setEmail(String[] email) {
            this.email = email;
        }
    
        public String getSubject() {
            return subject;
        }
    
        public void setSubject(String subject) {
            this.subject = subject;
        }
    
        public String getContent() {
            return content;
        }
    
        public void setContent(String content) {
            this.content = content;
        }
    
        public String getTemplate() {
            return template;
        }
    
        public void setTemplate(String template) {
            this.template = template;
        }
    
    
    }
    Email
     4:IEmailService接口
    import javax.mail.MessagingException;
    
    public interface IEmailService {
        public void send(Email email) throws MessagingException;//发送邮件
        public void pollQueue(Email email) throws InterruptedException;//把邮件放入队列中
    }
    IEmailService
       5:利用BlockingQueue保存Email
    package com.example.quartz.common.queue;
    
    
    import com.example.quartz.common.entity.Email;
    
    import java.util.concurrent.BlockingQueue;
    import java.util.concurrent.LinkedBlockingQueue;
    
    /**
     * 保存邮件的队列
     * 设计为单例模式
     */
    public class Mailqueue {
    
        public static final int QUEUE_SIZE = 100;
    
        public static BlockingQueue<Email> queue = new LinkedBlockingQueue<>(QUEUE_SIZE);
    
        public volatile static Mailqueue mailqueue ;
    
        /*
         *使用DCL模式
         */
        public static Mailqueue getSingleton()
        {
            if(mailqueue == null)
            {
                synchronized (Mailqueue.class)
                {
                    if(mailqueue == null)
                    {
                        mailqueue = new Mailqueue();
                    }
                }
            }
    
            return mailqueue;
        }
        //入队
        public void add(Email email) throws InterruptedException {
            queue.put(email);
        }
        //出队
        public Email poll() throws InterruptedException {
            return queue.take();
        }
        //队列大小
        public int size()
        {
            return queue.size();
        }
    
        private Mailqueue(){}
    
    }
    Mailqueue
       6:利用线程池的线程不断去读取队列是否存在Email,然后线程发送邮件
    import com.example.quartz.common.entity.Email;
    import com.example.quartz.service.IEmailService;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.stereotype.Component;
    
    import javax.annotation.PostConstruct;
    import javax.mail.MessagingException;
    import java.util.concurrent.ExecutorService;
    import java.util.concurrent.Executors;
    
    /**
     * 消费队列
     *
     */
    
    
    @Component
    public class ConsumeQueue {
        @Autowired
        IEmailService emailService;
    
        @PostConstruct
        public  void start()
        {
            ExecutorService pool = Executors.newFixedThreadPool(2);//固定两个线程的线程池
            pool.submit(new task()); //提交任务
        }
        class task implements  Runnable{
    
            @Override
            public void run() {
                System.out.println("等待接受任务");
                while(true)
                {
                    Email email = null;
                    try {
                        email = Mailqueue.getSingleton().poll();
                        System.out.println("接受到邮件");
                        if(email != null)
                        {
                                emailService.send(email);
                        }
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    } catch (MessagingException e) {
                        e.printStackTrace();
                    }
    
                }
            }
        }
    }
    ConsumeQueue
     7:EmailServiceImpl 
    import com.example.quartz.common.entity.Email;
    import com.example.quartz.common.queue.Mailqueue;
    import com.example.quartz.service.IEmailService;
    import freemarker.core.ParseException;
    import freemarker.template.*;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.beans.factory.annotation.Value;
    import org.springframework.mail.javamail.JavaMailSender;
    import org.springframework.mail.javamail.MimeMessageHelper;
    import org.springframework.stereotype.Service;
    import org.springframework.ui.freemarker.FreeMarkerTemplateUtils;
    
    import javax.mail.MessagingException;
    import javax.mail.internet.MimeMessage;
    import java.io.IOException;
    import java.io.UnsupportedEncodingException;
    import java.util.HashMap;
    import java.util.Map;
    
    
    @Service
    public class EmailServiceImpl implements IEmailService {
    
    
        @Autowired
        JavaMailSender mailSender;//用于发送邮件
        @Autowired
        Configuration configuration;//freemarker
        @Value("${spring.mail.username}")
        public String USER_NAME;//发送者
        @Value("${server.path}")
        public String PATH; //模板中的图片等静态资源路径
    
        /**
         * 把邮件放进队列中
         * @param email
         */
        @Override
        public void send(Email email)  {
            MimeMessage message = mailSender.createMimeMessage();
            MimeMessageHelper helper = null;
            try {
                helper = new MimeMessageHelper(message, true);
                helper.setFrom(USER_NAME,"通过模板发送邮件");
                helper.setTo(email.getEmail());//发送给谁
                helper.setSubject(email.getSubject());//主题
                Map<String, Object> model = new HashMap<>();
                model.put("mail",email);
                model.put("path",PATH);
                Template template = configuration.getTemplate(email.getTemplate());//获得模板
                String msg = FreeMarkerTemplateUtils.processTemplateIntoString(template, model);
                helper.setText(msg,true);
                mailSender.send(message);//正式发送邮件
            } catch (MessagingException e) {
                e.printStackTrace();
            } catch (ParseException e) {
                e.printStackTrace();
            } catch (UnsupportedEncodingException e) {
                e.printStackTrace();
            } catch (MalformedTemplateNameException e) {
                e.printStackTrace();
            } catch (TemplateNotFoundException e) {
                e.printStackTrace();
            } catch (IOException e) {
                e.printStackTrace();
            } catch (TemplateException e) {
                e.printStackTrace();
            }
    
    
        }
    
        @Override
        public void pollQueue(Email email) throws InterruptedException {
            Mailqueue.getSingleton().add(email);
        }
    }
    EmailServiceImpl
       8:web测试
    package com.example.quartz.web;
    
    
    import com.example.quartz.common.entity.Email;
    import com.example.quartz.service.IEmailService;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.web.bind.annotation.PostMapping;
    import org.springframework.web.bind.annotation.RequestBody;
    import org.springframework.web.bind.annotation.RequestMapping;
    import org.springframework.web.bind.annotation.RestController;
    
    @RestController
    @RequestMapping("/email")
    public class textContrller {
    
    
        @Autowired
        IEmailService emailService;
        @PostMapping
        public void sendEmail(@RequestBody Email email) throws InterruptedException {
            emailService.pollQueue(email);
        }
    }
    textContrller
      9:postman测试结果

     

      二:利用quartz实现定时发送邮件功能

    这里我只是设置定时任务把邮件放入队列中,quartz的简单应用,没有用过集群什么的。

        1:quartz实体
    package com.example.quartz.common.entity;
    
    public class QuartzEntity {
    
        private String jobName;//任务名称
        private String jobGroup;//任务分组
        private String description;//任务描述
        private String jobClassName;//执行类
        private String jobMethodName;//执行方法
        private String cronExpression;//执行时间
        private String triggerName;//执行时间
        private String triggerState;//任务状态
    
        public String getJobName() {
            return jobName;
        }
    
        public void setJobName(String jobName) {
            this.jobName = jobName;
        }
    
        public String getJobGroup() {
            return jobGroup;
        }
    
        public void setJobGroup(String jobGroup) {
            this.jobGroup = jobGroup;
        }
    
        public String getDescription() {
            return description;
        }
    
        public void setDescription(String description) {
            this.description = description;
        }
    
        public String getJobClassName() {
            return jobClassName;
        }
    
        public void setJobClassName(String jobClassName) {
            this.jobClassName = jobClassName;
        }
    
        public String getJobMethodName() {
            return jobMethodName;
        }
    
        public void setJobMethodName(String jobMethodName) {
            this.jobMethodName = jobMethodName;
        }
    
        public String getCronExpression() {
            return cronExpression;
        }
    
        public void setCronExpression(String cronExpression) {
            this.cronExpression = cronExpression;
        }
    
        public String getTriggerName() {
            return triggerName;
        }
    
        public void setTriggerName(String triggerName) {
            this.triggerName = triggerName;
        }
    
        public String getTriggerState() {
            return triggerState;
        }
    
        public void setTriggerState(String triggerState) {
            this.triggerState = triggerState;
        }
    }
    QuartzEntity
     2:MyJob构建
    import com.example.quartz.common.entity.Email;
    import com.example.quartz.common.queue.Mailqueue;
    import org.quartz.*;
    
    import java.io.Serializable;
    import java.lang.reflect.InvocationTargetException;
    import java.lang.reflect.Method;
    
    @DisallowConcurrentExecution
    public class MyJob implements Job , Serializable {
    
        private static final long serialVersionUID = 1L;
    
    
        @Override
        public void execute(JobExecutionContext context){
            JobDetail jobDetail = context.getJobDetail();
            JobDataMap dataMap = jobDetail.getJobDataMap();
            /**
             * 获取任务中保存的方法名字,动态调用方法
             */
            String methodName = dataMap.getString("jobMethodName");
            try {
                MyJob job = new MyJob();
                Method method = job.getClass().getMethod(methodName);
                method.invoke(job);
            } catch (NoSuchMethodException e) {
                e.printStackTrace();
            } catch (IllegalAccessException e) {
                e.printStackTrace();
            } catch (InvocationTargetException e) {
                e.printStackTrace();
            }
        }
    
        public  void test1() throws InterruptedException {
            System.out.println("执行任务");
                //往邮件队列中放入邮件
            Email email = new Email();
            email.setEmail(new String[]{"137846575@qq.com"});
            email.setContent("测试发送邮件");
            email.setSubject("定时发送邮件demo");
            email.setTemplate("hh.flt");
            Mailqueue.getSingleton().add(email);
        }
    }
    MyJob
       3:TaskRunner
    package com.example.quartz.job;
    
    import com.example.quartz.common.entity.QuartzEntity;
    import org.quartz.*;
    import org.slf4j.Logger;
    import org.slf4j.LoggerFactory;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.boot.ApplicationArguments;
    import org.springframework.boot.ApplicationRunner;
    import org.springframework.stereotype.Component;
    /**
     * 初始化任务
     */
    @Component
    public class TaskRunner  implements ApplicationRunner {
    
        private final static Logger LOGGER = LoggerFactory.getLogger(TaskRunner.class);
    
        @Autowired
        private Scheduler scheduler;
    
        @Override
        public void run(ApplicationArguments args) throws Exception {
            //初始化任务测试发送邮件
            QuartzEntity quartz = new QuartzEntity();
            quartz.setJobName("测试一下");
            quartz.setJobGroup("test");
            quartz.setDescription("测试定时任务发送邮件");
            quartz.setJobClassName("com.example.quartz.job.MyJob");
            quartz.setCronExpression("*/5 * * * * ?"); //每隔5秒发送邮件
            quartz.setJobMethodName("test1"); //具体的需要执行的定时任务逻辑方法名
            Class cls = Class.forName(quartz.getJobClassName());
            cls.newInstance();
            //构建job
            JobDetail job = JobBuilder.newJob(cls).withIdentity(quartz.getJobName(), quartz.getJobGroup())
                    .withDescription(quartz.getDescription()).build();
            job.getJobDataMap().put("jobMethodName","test1");
            //触发的时间点
            CronScheduleBuilder cronSchedule = CronScheduleBuilder.cronSchedule(quartz.getCronExpression());
            Trigger trigger = TriggerBuilder.newTrigger().withIdentity(quartz.getJobName(), quartz.getJobGroup())
                    .startNow().withSchedule(cronSchedule).build();
            scheduler.scheduleJob(job,trigger); //将job和trigger交给scheduler
        }
    }
    TaskRunner
      4:测试每隔5秒钟发送邮件

     

      5:freemarker模板文件
    <!doctype html>
    <html lang="zh-cmn-Hans">
    <head>
        <meta charset="UTF-8">
        <meta name="renderer" content="webkit" />
        <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1" />
        <title>Document</title>
    </head>
    <body>
        <div class="container"
             style="  800px;
             height: auto;
             margin: 0 auto;
             border: 1px #dddddd solid;
             border-top: 4px #3498db solid;
             font: 14px Microsoft Yahei;
             color: #333;">
            <div class="main" style="padding: 0 15px;">
                <div style="
                     border: 1px #f39d12 dashed;
                     background-color: #fffdf4;
                     margin: 20px 0;
                     border-radius: 6px;">
                    <table width="100%" style="border: none">
                        <tr>
                            <td style=" 20%; text-align: center; padding-top: 25px">
                                <img src="${path}/image/dog.png" alt="">
                            </td>
                            <td colspan="2" style="font-size: 18px; line-height: 1.6;padding-top: 30px">
                                <div style="text-indent: 36px; padding-right: 24px">
                                     ${mail.content}
                                </div>
                            </td>
                        </tr>
                    </table>
                </div>
            </div>
            <div class="footer" style="margin: auto;
                                padding: 15px 0 15px 15px;
                                background-color: #fafafa;
                                border-top: 1px #ddd solid;
                                color: #333;
                                height: auto;
                                zoom: 1;
                                overflow: auto;">
                <table style=" 100%">
                    <tr>
                        <td style=" 60%">
                            <h4 style="font-size: 16px;
                                 margin: 10px 0;">
                             大司马迷弟灰灰牛逼哄哄有限公司
                            </h4>
                            <p>
                                公司地址:
                                <b>宇宙银河系泰坦星泰坦星</b>
                            </p>
                            <p>
    
                            </p>
                            <p>
                                服务热线:
                                <b>
                                    <span style="display: inline-block; margin-right: 16px;">17762018584</span>
                                </b>
                            </p>
                        </td>
                        <td style="text-align: right;">
                            <div style=" display: inline-block; 120px ; padding-top: 10px; padding-right: 200px;">
                                <img src="${path}/image/dog.jpg" alt="" style="vertical-align: top">
                            </div>
                        </td>
                    </tr>
                </table>
            </div>
        </div>
    </body>
    </html> 
    hh.flt

    三:注意事项

    导入quartz依赖时导入的是

    <!--quartz定时调度依赖-->
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-quartz</artifactId>
    </dependency>
    

      不要导入

    <dependency>
                <groupId>org.quartz-scheduler</groupId>
                <artifactId>quartz</artifactId>
                <version>2.3.0</version>
            </dependency>
    

    四:参考

    https://gitee.com/52itstyle/spring-boot-quartz

    
    
  • 相关阅读:
    centos crash debug
    go get Unknown SSL protocol error in connection to gopkg.in
    Tensorflow serving with Kubernetes
    Spring 集成 Swagger UI
    Docker Registry V2 Garbage Collection
    Docker Registry V2 with Nginx
    Zabbix磁盘性能监控
    Zabbix CPU utilization监控参数
    Windows挂载Gluster复制卷
    Redis持久化存储(三)
  • 原文地址:https://www.cnblogs.com/swqblog/p/13082748.html
Copyright © 2011-2022 走看看