近期項目中有定時郵件推送的需求,經過一番實踐,最終實現,因此將開發步驟記錄下來:
涉及的技術:
SpringBoot:v1.5.13.RELEASE
Freemarker:2.0
Springcloud:Dalston.SR3
Quartz
1.引入依賴,分別爲SpringBoot對mail和freemarker模板的集成
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-mail</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-freemarker</artifactId>
</dependency>
2.配置發送郵箱,bootstrap.yml中配置如下
# 發送郵件配置
freemarker:
f
mail:
host: 127.0.0.0
port: xxx
username: xxx
password: xxx
properties:
mail:
smtp:
auth: true
starttls:
enable: true
required: true
ssl:
checkserveridentity: false
trust: 127.0.0.0
3.新建定時任務類JobBusiness ,實現BusinessAgent
public class JobBusiness implements BusinessAgent {
@Override
public void execute(String configId, Map jobMap, List jobList) {
JobService jobService = ApplicationObjectUtils.getBean(JobService.class);
jobService .sendMail();
}
}
4.新建發送郵件接口JobService
public interface JobService {
void sendMail();
}
5.新建發送郵件JobServiceImpl
@Service
public class JobServiceImpl extends MybatisManagerImpl implements JobService{
private static final Logger logger = LoggerFactory.getLogger(JobService.class);
@Autowired
private FreeMarkerConfigurer freeMarkerConfigurer;
@Autowired
private JavaMailSender javaMailSender;
private static final String FROM = "[email protected]";
private String toarray [] = {"[email protected]"};
private String bcc [] = {"[email protected]"};
@Override
public void sendMail() {
List<Map> list = this.myBatisDao.getSqlSession().selectList("geiMailQuery");
if(list.size() == 0){
log.info(""+getToday()+",沒有待推送的郵件,本次任務結束!");
return;
}
String title = "訂閱:xxx("+getToday()+")";
//initConfig();//獲取redis的收件人、抄送人郵箱
sendEmail(list,title,toarray, bcc, "Mail.ftl");
}
public R sendEmail(List<Map> list, String subject, String[] to, String[] cc, String templateName){
Long startTime = System.currentTimeMillis();
Map<String, Object> map = new HashMap<String, Object>();
map.put("list", list);
try {
if (StringUtils.isEmpty(subject)) {
log.error("發送郵件失敗,主題不能爲空!");
return R.success("發送郵件失敗,主題不能爲空!");
}
if (to.length == 0) {
log.error("發送郵件失敗,收件人不能爲空!");
return R.success("發送郵件失敗,收件人不能爲空!");
}
//調用發送模塊
MimeMessage mimeMessage = javaMailSender.createMimeMessage();
MimeMessageHelper helper = new MimeMessageHelper(mimeMessage, true);
//設置發件信息人
helper.setFrom(FROM);
//設置標題
helper.setSubject(subject);
helper.setTo(to);
//抄送
if (cc.length > 0) {
helper.setCc(cc);
}
//密送
//helper.setBcc(bccList);
//獲取模板
Configuration configuration = freeMarkerConfigurer.getConfiguration();
Template template = configuration.getTemplate(templateName, "UTF-8");
String text = FreeMarkerTemplateUtils.processTemplateIntoString(template, map);
helper.setText(text, true);
//發送
javaMailSender.send(mimeMessage);
//附件,後續支持
//Resource resource = new ClassPathResource("xxx.jpg");
//helper.addInline("contentId", resource);
Long endTime = System.currentTimeMillis();
log.info("郵件發送成功 耗時:" + (endTime - startTime) / 1000 + "s");
return R.success("郵件發送成功");
} catch (Exception e) {
log.error("發送郵件失敗:" + e.getMessage());
return R.success("郵件發送成功");
}
}
private String getToday(){
Date date = new Date();
return new SimpleDateFormat("yyyy-MM-dd").format(date);
}
注:R爲封裝的一個返回類,具體的返回類型可以自己定義
6.以163郵箱爲發送服務器(測試能發)
public R send163Email(List<Map> list, String subject, String[] to, String[] cc, String templateName){
Long startTime = System.currentTimeMillis();
Map<String, Object> map = new HashMap<String, Object>();
map.put("list", list);
Properties props = new Properties();
props.put("mail.smtp.host", "smtp.163.com");
props.put("mail.smtp.auth", "true");
props.put("username", "xxx");
props.put("password", "xxx");//此處爲smtp的密碼,非郵箱密碼
MimeMessage mimeMessage = null;
try {
if (StringUtils.isEmpty(subject)) {
log.error("發送郵件失敗,主題不能爲空!");
return R.success("發送郵件失敗,主題不能爲空!");
}
if (to.length == 0) {
log.error("發送郵件失敗,收件人不能爲空!");
return R.success("發送郵件失敗,收件人不能爲空!");
}
InternetAddress fromAddress = new InternetAddress("[email protected]");
// toemails(字符串,多個收件人用,隔開)
Session mailSession = Session.getDefaultInstance(props, new Authenticator() {
protected PasswordAuthentication getPasswordAuthentication() {
return new PasswordAuthentication("[email protected]", "xxx");//此處爲smtp的密碼,非郵箱密碼
}
});
mimeMessage = new MimeMessage(mailSession);
MimeMessageHelper helper = new MimeMessageHelper(mimeMessage, true);
//設置發件信息人
helper.setFrom(FROM);
//設置標題
helper.setSubject(subject);
helper.setTo(to);
//抄送
if (cc.length > 0) {
helper.setCc(cc);
}
//密送
//helper.setBcc(bccList);
//獲取模板
Configuration configuration = freeMarkerConfigurer.getConfiguration();
Template template = configuration.getTemplate(templateName, "UTF-8");
String text = FreeMarkerTemplateUtils.processTemplateIntoString(template, map);
helper.setText(text, true);
mimeMessage.saveChanges();
Transport.send(mimeMessage);
Long endTime = System.currentTimeMillis();
log.info("郵件發送成功 耗時:" + (endTime - startTime) / 1000 + "s");
} catch (Exception e) {
log.error("Error while sending mail." + e.getMessage(), e);
}
7.新建Mail.ftl郵件模板,位置:resources/templates
<!DOCTYPE html>
<html lang="zh">
<head>
<META http-equiv=Content-Type content='text/html; charset=UTF-8'>
<title>Title</title>
<style type="text/css">
table.gridtable {
font-family: verdana,arial,sans-serif;
text-align:center;
font-size:11px;
color:#333333;
border-width: 1px;
border-color: #666666;
border-collapse: collapse;
word-break: keep-all;
}
table.gridtable th {
border-width: 1px;
padding: 8px;
border-style: solid;
border-color: #666666;
background-color: #B7DEE8;
}
table.gridtable td {
border-width: 1px;
padding: 8px;
border-style: solid;
border-color: #666666;
background-color: #ffffff;
}
h3 {
font-size: 1.8em;
margin: 2px 0;
line-height: 1.8em;
}
</style>
</head>
<body>
<p style="font-family:"font-size:13px;background-color:#FFFFFF;">
各位同事大家好!
<div>
系統內以下數據異常,請覈實處理!
</div>
</p>
<table class="gridtable">
<tr>
<th>序號</th>
<th>xx</th>
<th>xx</th>
<th>xx</th>
<th>xx</th>
<th>xx</th>
<th>xx</th>
</tr>
<#list list as data>
<tr>
<th>
${data.xx}
</th>
<td>
${data.xx}
</td>
<td>
${data.xx}
</td>
<td>
<strong style="color:red">${data.xx}</strong>
</td>
<td>
<strong style="color:red">${data.xx?if_exists}</strong>
</td>
<td>
${data.xx?if_exists}
</td>
<td>
${data.xx?if_exists}
</td>
</tr>
</#list>
</table>
<p style="margin: 0px 0cm; widows: 1; font-size: 14px; line-height: 15.75pt; font-family: 宋體; text-align: justify; background-color: rgb(255, 255, 255);"><b><br /></b></p>
<p style="margin: 0px 0cm; widows: 1; font-size: 14px; line-height: 15.75pt; font-family: 宋體; text-align: justify; background-color: rgb(255, 255, 255);"><b><br /></b></p>
<p style="margin: 0px 0cm; widows: 1; font-size: 14px; line-height: 15.75pt; font-family: 宋體; text-align: justify; background-color: rgb(255, 255, 255);"><b><br /></b></p>
<span style="font-family:"font-size:13px;background-color:#FFFFFF;">xxx有限公司</span><br />
<span style="font-family:"font-size:13px;background-color:#FFFFFF;">xxx</span><br />
<p>
<span style="font-family:"font-size:13px;background-color:#FFFFFF;">郵箱:[email protected] </span>
</p>
<p>
<span style="font-family:"font-size:13px;background-color:#FFFFFF;">地址:xxx</span>
</p>
<hr color="red" size="“5”" style="font-size: 14px; line-height: 21px; font-family: Verdana;" />
<p style="margin: 0px 0cm; widows: 1; line-height: 15.75pt; font-size: 12pt; font-family: 宋體; background-color: rgb(255, 255, 255);"><span lang="EN-US" style="font-size: 10.5pt; font-family: Calibri, sans-serif; color: rgb(31, 73, 125);"><font size="1" style="color: rgb(0, 0, 0); widows: 2; font-family: Verdana;">系統定時發送,如果收件有誤,請將此郵件刪除,謝謝</font></span></p>
<br/>
<br/>
</body>
</html>
注意: 如果data.xxx可能爲null,則後面加:?if_exists,否則ftl頁面將報錯
8.收到的郵件如下圖