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

    
    
  • 相关阅读:
    Data Wrangling文摘:Non-tidy-data
    Data Wrangling文摘:Tideness
    Python文摘:Mixin 2
    Python文摘:Mixin
    Python文摘:Python with Context Managers
    Python学习笔记11
    SQL学习笔记9
    SQL学习笔记8
    SQL学习笔记7
    Python学习笔记10:内建结构
  • 原文地址:https://www.cnblogs.com/swqblog/p/13082748.html
Copyright © 2011-2022 走看看