背景

甲方爸爸:新接入业务在国庆以及军运会期间需要每天巡检业务并发送邮件告知具体情况!

我司:没问题。

甲方爸爸:假期也要发噢。

我司:没问题(。。。)。

刚开始计划指定几个同事轮流发送,业务只要不被攻击一般是没有问题的。但是想一想休息日还要处理工作上的事情(非紧急的)就不爽,近几年一直在做前端的事情,后台碰的少,毕竟也接触过,所以决定搞一个定时发送邮件的程序,遂上网查找资料。

邮件类选择

在网上大致上看了下,目前有两种方案:

  1. MimeMessage
        String title = createTitle();
String text = createText();
Properties props = new Properties();
props.put("mail.smtp.host", "smtp.qq.com");
props.put("mail.transport.protocol", "smtp");
props.put("mail.smtp.socketFactory.class", "javax.net.ssl.SSLSocketFactory");
props.put("mail.smtp.auth", "true");
Session session = Session.getDefaultInstance(props,
new javax.mail.Authenticator() {
protected PasswordAuthentication getPasswordAuthentication() {
return new PasswordAuthentication(from, passwd);
}
});
MimeMessage message = new MimeMessage(session);
try {
message.setFrom(new InternetAddress(from));
message.addRecipient(Message.RecipientType.TO, new InternetAddress(to));
message.setSubject(title);
message.setText(text);
System.out.println(text);
Transport.send(message);
} catch(Exception e) {
e.printStackTrace();
}
  1. SimpleMail
        mail.setHostName(host);
mail.setAuthentication(user, passwd);
mail.setFrom(user);
mail.setCharset("UTF-8");
mail.setSubject(title);
mail.setSSLOnConnect(true);
mail.setMsg(content);
mail.addTo(to);
mail.send();

在本地重构代码并进行了测试,都是正常发送和接收,个人觉得SimpleMail看起来更加简洁,所以邮件类就选它了

定时器

网上搜索一大堆,具体就不一一介绍了,我用的是Quartz

Quartz 设计有三个核心类,分别是

  • Scheduler 调度器

    调度器就相当于一个容器,装载着任务和触发器。该类是一个接口,代表一个 Quartz 的独立运行容器, TriggerJobDetail 可以注册到 Scheduler 中, 两者在 Scheduler 中拥有各自的组及名称, 组及名称是 Scheduler 查找定位容器中某一对象的依据, Trigger 的组及名称必须唯一, JobDetail 的组和名称也必须唯一(但可以和 Trigger 的组和名称相同,因为它们是不同类型的)。Scheduler 定义了多个接口方法, 允许外部通过组及名称访问和控制容器中 TriggerJobDetail
  • Job任务

    定义需要执行的任务。该类是一个接口,只定义一个方法 execute(JobExecutionContext context),在实现类的 execute 方法中编写所需要定时执行的 Job(任务), JobExecutionContext 类提供了调度应用的一些信息。Job 运行时的信息保存在 JobDataMap 实例中
  • Trigger 触发器

    负责设置调度策略。该类是一个接口,描述触发 job 执行的时间触发规则。主要有 SimpleTriggerCronTrigger 这两个子类。当且仅当需调度一次或者以固定时间间隔周期执行调度,SimpleTrigger 是最适合的选择;而 CronTrigger 则可以通过 Cron 表达式定义出各种复杂时间规则的调度方案:如工作日周一到周五的 15:00~16:00 执行调度等

开发测试

发送者邮箱必须开启客户端POP3/IMAP/SMTP/Exchange/CardDAV/CalDAV服务,具体可以在邮箱设置页进行设置,密码使用授权码

  1. 创建SendMail类,将发送邮件逻辑代码进行封装
public class SendMail implements Job {

	private static String user = "11111111@qq.com";
private static String passwd = "passwd";//授权码
private static String to = "22222@qq.com";
private static String host = "smtp.qq.com"; public static void sendMailForSmtp(String title, String content, String[] tos, String[] ccs) throws EmailException {
SimpleEmail mail = new SimpleEmail();
// 设置邮箱服务器信息
mail.setHostName(host);
// 设置密码验证器passwd为授权码
mail.setAuthentication(user, passwd);
// 设置邮件发送者
mail.setFrom(user);
// 设置邮件编码
mail.setCharset("UTF-8");
// 设置邮件主题
mail.setSubject(title);
//SSL方式
mail.setSSLOnConnect(true);
// 设置邮件内容
// mail.setMsg(content);
// 设置邮件接收者
// mail.addTo(to);
mail.addTo(tos);
mail.addCc(ccs);
// 发送邮件
MimeMultipart multipart = new MimeMultipart();
//邮件正文
BodyPart contentPart = new MimeBodyPart();
try {
contentPart.setContent(content, "text/html;charset=utf-8");
multipart.addBodyPart(contentPart);
//邮件附件
BodyPart attachmentPart = new MimeBodyPart();
File file = new File("C:\\lutong\\20190918002.log");
FileDataSource source = new FileDataSource(file);
attachmentPart.setDataHandler(new DataHandler(source));
attachmentPart.setFileName(MimeUtility.encodeWord(file.getName()));
multipart.addBodyPart(attachmentPart);
mail.setContent(multipart);
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
} catch (MessagingException e) {
e.printStackTrace();
}
System.out.println(JsonUtil.toJson(mail));
mail.send();
System.out.println("mail send success!");
}
@Override
public void execute(JobExecutionContext var1) throws JobExecutionException {
// TODO Auto-generated method stub
//多个接收者
String[] tos = {"11111@qq.com","2222@qq.com"};
//多个抄送者
String[] ccs = {"33333@qq.com","44444@qq.com"};
try {
SendMail.sendMailForSmtp("title", "hello <br> ccy", tos, ccs);
} catch (EmailException e) {
e.printStackTrace();
}
}
}
  1. 创建CronTrigger,定时发送任务
public class CronTrigger {
public static void main(String[] args){
//初始化job
JobDetail job = JobBuilder.newJob(SendMail.class)// 创建 jobDetail 实例,绑定 Job 实现类
.withIdentity("ccy", "group1")//指明job名称、所在组名称
.build();
//定义规则
Trigger trigger = TriggerBuilder
.newTrigger()
.withIdentity("ccy", "group1")//triggel名称、组
.withSchedule(CronScheduleBuilder.cronSchedule("0/5 * * * * ?"))//每隔5s执行
.build();
Scheduler scheduler = null;
try {
scheduler = new StdSchedulerFactory().getScheduler();
System.out.println("start job...");
//把作业和触发器注册到任务调度中
scheduler.scheduleJob(job, trigger);
//启动
scheduler.start();
} catch (SchedulerException e) {
e.printStackTrace();
}
}
}

测试结果

后记

技术沟通群欢迎加入



如果对笔者感兴趣也欢迎你加我好友一起讨论技术,夸夸白

本人微信gm4118679254

Java定时发送邮件的更多相关文章

  1. java实现qq邮箱每天定时发送邮件

    本周四的时候去学校的某机构值班,主要工作是帮老师送文件,干一些杂活.那天没有什么活儿,于是想起用Java实现发送邮件和接收邮件的功能.前几天接触过一点quartz框架,用来实现定时开始任务的功能.于是 ...

  2. spring利用javamail,quartz定时发送邮件 <转>

    原文地址:spring利用javamail,quartz定时发送邮件 <转>作者:物是人非 spring提供的定时发送邮件功能,下面是一个简单的例子以供大家参考,首先从spring配置文件 ...

  3. Android 发送邮件以及定时发送邮件的实现

    本文以腾讯企业邮箱为例,展示如何发送邮件 及相关问题  选择腾讯企业邮箱是因为腾讯企业邮箱一般都是开启了smtp服务 项目地址:https://gitee.com/bimingcong/MySendE ...

  4. VBS实现定时发送邮件

    原理:建立CDO.Message对象,设置好参数后直接Send就可以了 代码如下: NameSpace = "http://schemas.microsoft.com/cdo/configu ...

  5. JAVA定时执行任务,每天定时几点钟执行任务

    JAVA定时执行任务,每天定时几点钟执行任务的示例如下: 1.建立TimerManage类,设置时间点,时间点设置的管理类,代码如下: package com.pcitc.time; import j ...

  6. python (18)在linux中如何实现定时发送邮件

    最近要用到,定时发送邮件功能: 如何定时,当然要用到linux中crontab了 如下的代码能够定时发送邮件 #!/usr/bin/env python # -*- coding=utf-8 -*- ...

  7. odoo定时发送邮件

    采购订单延迟或者存在部分到货的情况,定时发送邮件给相关人员 包含,采购订单明细,订单数量,已到货数量,未到货数量 <?xml version="1.0" encoding=& ...

  8. Java学习笔记 -- Java定时调度工具Timer类

    1 关于 (时间宝贵的小姐姐请跳过) 本教程是基于Java定时任务调度工具详解之Timer篇的学习笔记. 什么是定时任务调度 基于给定的时间点,给定的时间间隔或者给定的执行次数自动执行的任务. 在Ja ...

  9. Spring Boot 揭秘与实战(七) 实用技术篇 - Java Mail 发送邮件

    文章目录 1. Spring Boot 集成 Java Mail 2. 单元测试 3. 源代码 Spring 对 Java Mail 有很好的支持.因此,Spring Boot 也提供了自动配置的支持 ...

随机推荐

  1. Java源码之阻塞队列

    ⑴背景 阻塞队列常用于生产者消费者场景,生产者是向队列里添加元素的线程,消费者是向队列里取出元素的线程.阻塞队列的角色是供生产者存放元素,消费者取出元素的容器. ⑵阻塞队列 阻塞队列是一个支持两个附加 ...

  2. 浅谈python中文件和文件夹的相关操作

    文件操作 文件的打开与关闭 打开文件 使用open(文件名,访问方式)函数,可以打开一个已存在的文件,或者创建一个新的文件. 示例如下: f = open('test.txt') # 访问方式可以省略 ...

  3. (三)(1)线程间通信---wait和notify的使用

    这篇博客记录线程间通信相关api使用以及理解. 首先第一点,我之前的博客里的线程之间也是通信的,但是他们的通信是建立在访问的是同一个变量上的,相当于是变量.数据层面上的通信,而下面要讲的是线程层面上的 ...

  4. OSI七层网络模型与TCP/IP四层模型

    1.OSI七层结构图: 2.TCP/IP四层结构图: 3.各层对应的协议 4.OSI七层和TCP/IP四层的区别 OSI网络模型和TCP/IP网络模型对应关系: 5.交换机工作在OSI的哪一层 如果有 ...

  5. SSH原理讲解与实践

    一.简介 SSH全名Secure Socket Shell,安全外壳传输协议.专为远程登录会话和其他网络服务提供安全性的协议 二.加密算法 要了解SSH的原理,就要先知道目前主流的俩种加密算法 2.1 ...

  6. 2019牛客暑期多校训练营(第十场)J - Wood Processing (斜率优化DP)

    >传送门< 题意 $n$个宽度为$w_{i}$,高为$h_{i}$ 的 木块,要求分成$k$组,对于每组内的所有木块,高度都变为组内最低木块的高度,宽度保持不变,求变化的最小面积. 分析 ...

  7. Vue函数式组件的应用

    一.函数式组件和普通组件的区别 渲染快 没有实例,意味着没有(this) 没有生命周期(没有响应式数据) 二.组件函数的使用 1. 以局部组件为例,将组件标记为 functional=ture; 因为 ...

  8. 算法与数据结构基础 - 贪心(Greedy)

    贪心基础 贪心(Greedy)常用于解决最优问题,以期通过某种策略获得一系列局部最优解.从而求得整体最优解. 贪心从局部最优角度考虑,只适用于具备无后效性的问题,即某个状态以前的过程不影响以后的状态. ...

  9. Chrome 开发工具之 Application

    Chrome 开发者工具有 Application 这么一个面板,主要作用是检查 web 应用加载的所有资源,包括 Manifest.Service Workers.Local Storage.Ses ...

  10. Linux之Shell编程(16)

    读取从控制台输入的值(read): 系统函数: basename:返回完整路径最后/部分,常用于获取文件名 basename [pathname] [suffix] dirname:返回完整路径最后/ ...