定时器,定时发邮件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(); } } } }