定时器,定时发邮件JavaMail

一、定时器用法:

1.1先导入jar包

 <!--spring整合其他文件时要用的jar包-->
    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-context-support</artifactId>
      <version>${spring.version}</version>
    </dependency>
    <!--定时任务-->
    <dependency>
      <groupId>org.quartz-scheduler</groupId>
      <artifactId>quartz-jobs</artifactId>
      <version>2.3.1</version>
    </dependency>
    <dependency>
      <groupId>org.quartz-scheduler</groupId>
      <artifactId>quartz</artifactId>
      <version>2.3.0</version>
    </dependency>

1.2然后创建spring和quartz的整合配置文件  applicationContext-quartz.xml

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">

    <!--1.Job作业-->
    <bean id="app01" class="com.ujy.jobs.JobApp01"></bean>
    <!--JobDetail-->
    <bean id="jobDetail" class="org.springframework.scheduling.quartz.MethodInvokingJobDetailFactoryBean">
        <property name="targetObject" ref="app01"/>
        <property name="targetMethod" value="printSomething"/>
    </bean>
    <!-- 3.配置Trigger触发器 -->
    <bean id="simpleTrigger" class="org.springframework.scheduling.quartz.SimpleTriggerFactoryBean">
        <!-- see the example of method invoking job above -->
        <property name="jobDetail" ref="jobDetail" />
        <!-- 10 seconds -->
        <property name="startDelay" value="10000" />
        <!-- repeat every 50 seconds -->
        <property name="repeatInterval" value="5000" />
    </bean>
<!--     4.石英触发器:-->
    <bean id="cronTrigger" class="org.springframework.scheduling.quartz.CronTriggerFactoryBean">
        <property name="jobDetail" ref="jobDetail" />
        <!-- run every morning at 6 AM -->
        <property name="cronExpression" value="0/5 * * * * ?" />
    </bean>

    <!--  4.配置scheduler 容器-->
    <bean class="org.springframework.scheduling.quartz.SchedulerFactoryBean">
        <property name="triggers">
            <list>
<!--                <ref bean="simpleTrigger" />-->
                <ref bean="cronTrigger"/>
            </list>
        </property>
    </bean>

</beans>

1.3创建一个包,包中创建一个类,类中创建一个方法。就是用来执行的方法。

public class JobApp01 {
    public void printSomething(){
        System.out.println("您好啊!。。。");
    }
}

然后写main方法进行加载 。  因为石英触发器 底层使用的多线程,所以不能使用测试类进行测试。

public class QuartzTest {
    //quartz底层是使用了多线程 ,不能使用测试方法。
    public static void main(String[] args) {
        ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("applicationContext-quartz.xml");
       // context.getBean(AppTest.class);
    }
}

1.4 石英触发器表达式的用法:

cronExpression表达式:
1.基本格式[用空格分开的六位或者七位组成的表达式]
按顺序依次为
①秒(0~59)
②分钟(0~59)
③小时(0~23)
④天(月)(0~30,但是你需要考虑你月的天数)
⑤月【day of month】(0~11)
⑥天(星期)【day of week】(1~7 1=SUN 或 SUN,MON,TUE,WED,THU,FRI,SAT)
⑦年份(1970-2099)
设置方式:
①、指定具体值:5
②、连续区间:9-12
③、有间隔的区间:8-18/4
斜杠后面为间隔跨度
④、具体值的列表

通配符:
[1]*:表示在取值范围内的所有时间点都执行调度任务
例如:用*指定秒,表示每秒都执行任务;用*指定星期表示一周内的每一天都执行任务
[2]/:用于表示时间间隔
例如:用*/5指定秒,表示每隔5秒执行一次任务。
[3]?:仅用于day-of-month字段或day-of-week字段,表示不指定值。由于某个月的几号和星期几很难统一
成同一天。所以为了避免冲突,这两个字段必须有一个字段设置为?

每一天 9点24分 23,26,27分别执行该定时任务

示例:
表达式 说明
=========================================================================
秒 分 时 日 月 星期 年

0 19 9 * * ? 每天9点19分触发
0 15 10 ? * * 每天上午10:15触发
0 15 10 * * ? 每天上午10:15触发
0 15 10 * * ? * 每天上午10:15触发
0 15 10 * * ? 2005 2005年每天上午10:15触发

二、发送email的技术:JavaMail

2.1导入jar包:

<dependency>
        <groupId>javax.mail</groupId>
        <artifactId>mail</artifactId>
        <version>1.4</version>
    </dependency>

2.2 配置spring发送Email的配置文件

<!-- 1.发送Email 的类对象-->
     <bean class="org.springframework.mail.javamail.JavaMailSenderImpl">
           <!-- 配置邮箱账号 -->
          <property name="username" value="15294818079@163.com"/>
          <!-- 这个不是邮箱密码,而是配置 授权码-->
          <property name="password" value="123abc"></property>
         <!-- 设置编码格式 -->
         <property name="defaultEncoding" value="UTF-8"/>
         <!-- 配置smtp服务器-->
         <property name="host" value="smtp.163.com"></property>

         <!-- 邮箱服务器属性设置 -->
         <property name="javaMailProperties">
             <props>
                 <!-- 邮箱服务器是否支持验证 -->
                 <prop key="mail.smtp.auth">true</prop>
                 <!-- 邮箱服务器连接超时时间  毫秒-->
                 <prop key="mail.smtp.timeout">300000</prop>
             </props>
         </property>
     </bean>

 然后在controller层编写

package com.ujy.info.controller;

import com.ujy.emp.pojo.Employee;
import com.ujy.emp.service.ArchiveService;
import com.ujy.info.pojo.Email;
import com.ujy.info.service.EmailService;
import com.ujy.jobs.EmailJob;
import org.apache.commons.io.IOUtils;
import org.quartz.*;
import org.quartz.impl.StdSchedulerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.mail.javamail.JavaMailSenderImpl;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.ServletContext;
import javax.servlet.http.HttpSession;
import java.io.File;
import java.io.FileOutputStream;

import java.util.Date;
import java.util.HashMap;
import java.util.Map;
import java.util.UUID;

@Controller
@RequestMapping("/email")
public class EmailController {

    @Autowired
    private JavaMailSenderImpl javaMailSender;

    @Autowired
    private ArchiveService archiveService;

    @Autowired
    private EmailService emailService;

    @RequestMapping(value = "saveInfo",method = RequestMethod.POST)
    public  String saveInfo(Email email, MultipartFile file, HttpSession session){
            //通过员工的id 拿到档案表里面的邮箱 。 员工表的emp_fk对应着archives表的emp_fk
        String emailAddress = archiveService.getEmailByEid(email.getEmpFk());
        //下面的这些 就是把上传的文件 保存到本地服务器。
        ServletContext servletContext = session.getServletContext();
        String realPath = servletContext.getRealPath("/upload");
        File directory = new File(realPath);


        if(!directory.exists()){
            directory.mkdirs();
        }
        String  fileName = UUID.randomUUID().toString().replaceAll("-", "")+file.getOriginalFilename();
        //将上传的文件保存在本地服务器里面 ,目录 和文件中间应有一个斜杠
        try {
            //file.transferTo(new File(realPath+"\"+fileName));   //第一种方式
            //  System.out.println(realPath+"\"+fileName);
            //  第二种方式将输入流的东西 直接转到输出流中
            IOUtils.copy(file.getInputStream(),new FileOutputStream(new File(realPath+"\"+fileName)));

            email.setPath(fileName);  //这个文件就有路径 ,然后保存到邮件路径里面

--------------------------------------------------------
//下面使用定时发送邮件 发送定时任务四个组件。 //2创建JobDetail对象,指定对象的任务名称、组名 通过newJob把job作业传过来,这样当我们访问这个方法时,会自动调用EmailJob下的execute这个方法。 //withIdentitytity 就是起个名字 ,然后分个组 JobDetail jobDetail = JobBuilder.newJob(EmailJob.class).withIdentity("job1", "group1").build(); JobDataMap jobDataMap = jobDetail.getJobDataMap(); //通过这个方法,把email 传给发送邮件的job作业,进行定时发送。 jobDataMap.put("email",email); jobDataMap.put("javaMailSender",javaMailSender); jobDataMap.put("emailAddress",emailAddress); jobDataMap.put("file",file); jobDataMap.put("fileAddress",realPath+"/"+fileName); //获取当前时间 // Long startTime = new Date().getTime()+180000L; //模拟3分钟后发送 Date time = new Date(); //模拟一个当前时间 让它立马发送 //3创建SimpleTrigger对象,指定对象名称、组名 设置任务重复执行间隔时间,重复执行次数 启动时间 通过TriggerBuilder.newTrigger()就可以得到trigger对象。 SimpleTrigger trigger = (SimpleTrigger) TriggerBuilder.newTrigger().withIdentity("trigger1", "group1").startAt(time).build(); //4创建任务管理器Scheduler对象 Scheduler sched= StdSchedulerFactory.getDefaultScheduler(); jobDataMap.put("sched",sched); //为Scheduler对象新增JOB以及对应的SimpleTrigger //用schedule把jobDetail 和trigger管理起来 sched.scheduleJob(jobDetail, trigger); //启动定时任务管理器 sched.start(); //保存到数据库中一份 。 Employee emp = (Employee) session.getAttribute("loginUser"); String ename = emp.getEname(); email.setEname(ename); emailService.saveInfo(email); } catch (Exception e) { e.printStackTrace(); } return "message"; } }

然后编写 发送邮件  进行发送

public class EmailJob implements Job {


    @Override
    public void execute(JobExecutionContext jobExecutionContext) throws JobExecutionException {
        //通过getMergedJobDataMap() 得到controller层传过来的邮件 进行定时发送。

        JobDataMap mergedJobDataMap = jobExecutionContext.getMergedJobDataMap();
        Email email = (Email) mergedJobDataMap.get("email");
        JavaMailSenderImpl javaMailSender= (JavaMailSenderImpl)mergedJobDataMap.get("javaMailSender");

        MultipartFile file = (MultipartFile) mergedJobDataMap.get("file");
        String emailAddress = (String)mergedJobDataMap.get("emailAddress");
        String fileAddress = (String) mergedJobDataMap.get("fileAddress");
        Scheduler sched = (Scheduler) mergedJobDataMap.get("sched");
        try{
            //1.得到邮件对象
            MimeMessage mimeMessage = javaMailSender.createMimeMessage();
            MimeMessageHelper helper = new MimeMessageHelper(mimeMessage,true,"UTF-8");
            //发送人邮箱,要和容器中 的邮箱保持一致
            helper.setFrom("15225283291@163.com");
            helper.setTo(emailAddress);
            helper.setSubject(email.getTitle());
            helper.setText(email.getContent(),true);

            //  is= new InputStreamResource(file.getInputStream());  以流的方式取出那个邮件
            FileSystemResource fileSystemResource = new FileSystemResource(new File(fileAddress));
            helper.addAttachment(file.getOriginalFilename(), fileSystemResource);
            javaMailSender.send(mimeMessage);
            System.out.println("邮件发送成功!");
        }catch (Exception ex){
            ex.printStackTrace();
        }finally {
            try {
                if (!sched.isShutdown())
                sched.shutdown();
            } catch (SchedulerException e) {
                e.printStackTrace();
            }
        }

    }

}
原文地址:https://www.cnblogs.com/ych961107/p/11983416.html