根据生日定时发送生日祝福邮件

需求

根据不同的生日日期,在生日当天发送一个祝福邮件,这是需要做到两个事情

  1. 定时,根据生日定时到每年的那一天
  2. 发送邮件

定时发送

要想做到定时发送,这时就需要一个定时任务调度的工具,这里使用的是Quartz
Quartz是一个定时任务调度框架,主要包含三个部分,Schedule(调度器)、
JobDetail(任务)CronTrigger(触发器)

  1. Scheduler
    调度器主要是调度调度规则,在规则下启动任务
Scheduler scheduler = StdSchedulerFactory.getDefaultScheduler();
  1. 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))         
                
    
  2. 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的表达式设置生日,进行定时转发
这里采用配置式,方便对任务的分组和批量管理

将自动发送邮件作为任务

public class MyJob3 implements Job{
    @Autowired
    private UserDao userDao;
    @Override
    public void execute(JobExecutionContext jobExecutionContext) throws JobExecutionException {
        Calendar calendar=Calendar.getInstance();
        int birth_year=calendar.get(Calendar.YEAR);
        int birth_month=calendar.get(Calendar.MONTH)+1;
        int birth_day=calendar.get(Calendar.DAY_OF_MONTH);
        User u=new User();
        u.setBirth_year(birth_year);
        u.setBirth_month(birth_month);
        u.setBirth_day(birth_day);
        List<User> users = userDao.selectUserByBirthday(u);
        for (User user : users) {
            String from ="xxxxxxxx@qq.com";
            String to=user.getEmail();
            String subject="生日祝福";
            String context="今天是您"+(birth_year-user.getBirth_year()+1)+"的生日,祝你生日快乐";
            try {
                SendMessage.sendMessage(from,to,subject,context);
            } catch (MessagingException e) {
                e.printStackTrace();
            }
        }
    }
}


//调用SendMessage方法
public class SendMessage{
    public static void sendMessage(String from,String to,String subject,String context) throws MessagingException {
        //设置邮箱服务器类型
        String host = "smtp.qq.com";
        //设置第三方登录使用验证码
        String auth = "xxxxxxxxxxx";
        //获取本地系统参数
        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("发送成功");
    }

}

配置文件

因为生日是从数据库中读取的,使用到了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版本低,造成字段映射失败,主要是德鲁伊不支持该类型的字段映射
解决:

  1. 更新德鲁伊的版本,下载对应的映射包

  2. 或者将生日字段分开;
    在这里插入图片描述
    在设置日期是可以使用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);
  • 0
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值