定時傳送郵件
背景
甲方爸爸:新接入業務在國慶以及軍運會期間需要每天巡檢業務併傳送郵件告知具體情況!
我司:沒問題。
甲方爸爸:假期也要發噢。
我司:沒問題(。。。)。
剛開始計劃指定幾個同事輪流傳送,業務只要不被攻擊一般是沒有問題的。但是想一想休息日還要處理工作上的事情(非緊急的)就不爽,近幾年一直在做前端的事情,後臺碰的少,畢竟也接觸過,所以決定搞一個定時傳送郵件的程式,遂上網查詢資料。
郵件類選擇
在網上大致上看了下,目前有兩種方案:
- 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();
}
複製程式碼
- 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
的獨立執行容器,Trigger
和JobDetail
可以註冊到Scheduler
中, 兩者在Scheduler
中擁有各自的組及名稱, 組及名稱是Scheduler
查詢定位容器中某一物件的依據,Trigger
的組及名稱必須唯一,JobDetail
的組和名稱也必須唯一(但可以和Trigger
的組和名稱相同,因為它們是不同型別的)。Scheduler
定義了多個介面方法, 允許外部通過組及名稱訪問和控制容器中Trigger
和JobDetail
- Job任務
定義需要執行的任務。該類是一個介面,只定義一個方法
execute(JobExecutionContext context)
,在實現類的execute
方法中編寫所需要定時執行的Job
(任務),JobExecutionContext
類提供了排程應用的一些資訊。Job
執行時的資訊儲存在JobDataMap
例項中 - Trigger 觸發器
負責設定排程策略。該類是一個介面,描述觸發
job
執行的時間觸發規則。主要有SimpleTrigger
和CronTrigger
這兩個子類。當且僅當需排程一次或者以固定時間間隔週期執行排程,SimpleTrigger
是最適合的選擇;而CronTrigger
則可以通過Cron
表示式定義出各種複雜時間規則的排程方案:如工作日週一到週五的15:00~16:00
執行排程等
開發測試
傳送者郵箱必須開啟客戶端POP3/IMAP/SMTP/Exchange/CardDAV/CalDAV服務,具體可以在郵箱設定頁進行設定,密碼使用授權碼
- 建立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();
}
}
}
複製程式碼
- 建立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