根据不同的生日日期,在生日当天发送一个祝福邮件,这是需要做到两个事情
定时,根据生日定时到每年的那一天发送邮件要想做到定时发送,这时就需要一个定时任务调度的工具,这里使用的是Quartz Quartz是一个定时任务调度框架,主要包含三个部分,Schedule(调度器)、 JobDetail(任务)CronTrigger(触发器)
Scheduler 调度器主要是调度调度规则,在规则下启动任务 Scheduler scheduler = StdSchedulerFactory.getDefaultScheduler(); CronTrigger 触发器中可以设置任务的触发规则 主要属性: startNow():设置起始时间为即时启动 **withSchedule:**设置任务的执行规律和执行次数 withIntervalInSecos() :每隔多长时间执行,时间单位是秒 repeatForever():持续循环执行,直到结束 endAt: 触发器的结束时间 因为使用的是CronTrigger,所以时间表达式按照cron的规则 依次为(秒 分 时 日 月 星期 (年(可选))) 特殊符号: **,**并列 - 区间,范围 / 间隔,从起始点间隔多长时间 ***** 任意值 **?**不确定值SimpleTrigger trigger = TriggerBuilder.newTrigger() trigger.startNow(); trigger.withSchedule(SimpleScheduleBuilder.simpleSchedule() .withIntervalInSeconds(1) //每秒执行一次 .repeatForever()); trigger.endAt(new Date(120,8,3,12,45,0)) JobDetial 创建新任务要实现Job接口,重写execute方法 public class Myjob implements Job { @Override public void execute(JobExecutionContext context) throws JobExecutionException { // System.out.println("执行方法"); } } 最后要将任务和触发器交给调度器调度 Trigger trigger = triggerBuilder.build(); //将任务交给触发器 JobDetail job =JobBuilder.newJob(Myjob.class).build(); //将触发器交给调度器 scheduler.scheduleJob(job,trigger); //启动调度器 scheduler.start();调度器:ScheduleFacrotyBean 任务:JobDetailFactoryBean 触发器:CronTriggerFactoryBean
<!--配置任务--> <bean name="jobDetail" class="org.springframework.scheduling.quartz.JobDetailFactoryBean"> <property name="name" value="myjob"/> <property name="group" value="mygroup"/> <property name="jobClass" value="quartz.MyJob3"/> </bean> <!--配置调度规则--> <bean name="cronTrigger" class="org.springframework.scheduling.quartz.CronTriggerFactoryBean"> <property name="jobDetail" ref="jobDetail"/> <property name="cronExpression" value="* * * * * ?"/> </bean> <!--配置调度器--> <bean name="" class="org.springframework.scheduling.quartz.SchedulerFactoryBean"> <property name="triggers"> <list> <ref bean="cronTrigger"></ref> </list> </property> </bean>要使用注解,首先要扫描目标文件,获取注解解析器
<context:component-scan base-package="quartz"/> <task:annotation-driven/>使用@Schedule注解
导入相关的jar包: 想要发送邮件,首先要有一个邮件平台 比如腾讯、新浪,并且要开启邮箱的授权码,获得授权码之后才能进行自动转发
public static void sendMessage() throws MessagingException { //设置邮箱服务器类型 String host = "smtp.qq.com"; //设置第三方登录使用验证码 String auth = "xxxxxxxxx"; //设置发件人 Stirng form="xxxxx@qq.com"; //设置收件人 String to="xxxxxx@qq.com"; //获取本地系统参数 Properties properties=System.getProperties(); //设置邮件服务器地址 properties.setProperty("mail.smtp.host",host); //告诉邮件客户端,本次请求是需要认证的 properties.put("mail.smtp.auth", "true"); //获取邮件服务器连接 Session session=Session.getDefaultInstance(properties, new Authenticator() { @Override public PasswordAuthentication getPasswordAuthentication() { return new PasswordAuthentication(from,auth); } }); //组装邮件内容 MimeMessage message = new MimeMessage(session); //发送人 message.setFrom(new InternetAddress(from)); //接收人 message.addRecipient(MimeMessage.RecipientType.TO,new InternetAddress(to)); //邮件主题 message.setSubject(subject); //邮件内容 message.setText(context); //发送邮件 Transport.send(message); System.out.println("发送成功"); }分别实现了定时任务调度和自动转发邮件之后,就可以将自动转发当做一个Job,通过CronTrigger的表达式设置生日,进行定时转发 这里采用配置式,方便对任务的分组和批量管理
因为生日是从数据库中读取的,使用到了ssm框架进行整合 在spring配置文件中配置定时任务调度
<beans xmlns="http://www.springframework.org/schema/beans" xmlns:context="http://www.springframework.org/schema/context" xmlns:aop="http://www.springframework.org/schema/aop" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:tx="http://www.springframework.org/schema/tx" xmlns:task="http://www.springframework.org/schema/task" xmlns:mybatis="http://mybatis.org/schema/mybatis-spring" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd http://mybatis.org/schema/mybatis-spring http://mybatis.org/schema/mybatis-spring.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx.xsd http://www.springframework.org/schema/task http://www.springframework.org/schema/task/spring-task.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd"> <!--配置任务--> <bean name="jobDetail" class="org.springframework.scheduling.quartz.JobDetailFactoryBean"> <property name="name" value="myjob"/> <property name="group" value="mygroup"/> <property name="jobClass" value="quartz.MyJob3"/> </bean> <!--配置调度规则--> <bean name="cronTrigger" class="org.springframework.scheduling.quartz.CronTriggerFactoryBean"> <property name="jobDetail" ref="jobDetail"/> <property name="cronExpression" value="0 0 6 * * ?"/> </bean> <!--配置调度器--> <bean name="" class="org.springframework.scheduling.quartz.SchedulerFactoryBean"> <property name="triggers"> <list> <ref bean="cronTrigger"></ref> </list> </property> </bean> <!-- 配置数据库配置文件--> <context:property-placeholder location="classpath:jdbc.properties"/> <bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource"> <property name="url" value="${url}"/> <property name="username" value="${jdbc.userName}"/> <property name="password" value="${password}"/> </bean> <bean class="org.mybatis.spring.SqlSessionFactoryBean"> <property name="dataSource" ref="dataSource"/> <property name="mapperLocations" value="classpath*:Dao/*.xml"/> </bean> <mybatis:scan base-package="Dao"/> </beans>为了方便对任务调度器的管理,可以根据任务的分组和命名进行管理和批量操作,可以在Controller层,通过页面请求 对Schedule进行操作 停止 Schedule.pauseJob()
scheduler.pauseJob(JobKey.jobKey("jobName","groupName"))重新开始 Schedule.resumeJob()
scheduler.resumeJon(JobKey.jobKey("jobName","groupName"))删除 Schedule.deleteJob()
scheduler.deleteJob(JobKey.jobKey("jobName","groupName"))在数据库映射数据时,数据库的生日字段使用的是data类型的存储方式,在映射的过程中可能会出现下面的错误
异常: 原因:Druid版本低,造成字段映射失败,主要是德鲁伊不支持该类型的字段映射 解决:
更新德鲁伊的版本,下载对应的映射包
或者将生日字段分开; 在设置日期是可以使用Calendar获取设置时间:
Calendar calendar=Calendar.getInstance(); //获取int型的年份 int birth_year=calendar.get(Calendar.YEAR); //获取int型的月份(0-11) int birth_month=calendar.get(Calendar.MONTH)+1; //获取对应月份的日(自动区分日期) int birth_day=calendar.get(Calendar.DAY_OF_MONTH);