一、先介绍下JavaMailSender
上一篇使用Quartz实现了简单的定时任务,定时任务的用途非常广泛,接下来使用Quartz和JavaMailSender实现一下定时发邮件的功能。
JavaMailSender是Spring封装的邮件发送封装类,支持普通文本、附件、html等格式。
二、整合JavaMailSender
如果邮件依赖中没有spring-context-support的支持,可以单独添加该依赖。
org.springframework.boot
spring-boot-starter-quartz
org.springframework.boot
spring-boot-starter-mail
2. .yml文件进行相关配置
这里主要对邮箱进行配置,包括QQ邮箱,163邮箱等等。Demo主要用163邮箱演示,163邮箱使用的密码不要Unicode转码(可能会报535错误),而如果使用QQ邮箱需要去QQ邮箱设置并生成授权码(自己百度设置的方法吧)。
---
#---------------------JavaMailSender 邮箱配置--------------------------
#网易163邮箱
spring:
mail:
host: smtp.163.com
username: 邮箱账号
password: 邮箱密码
properties:
mail:
smtp:
# 需要验证登录名和密码
auth: true
starttls:
# 需要TLS认证 保证发送邮件安全验证
enable: true
required: true
---
# QQ邮箱
#spring:
# mail:
# host: smtp.qq.com
# username: QQ邮箱账号
# #这个不是QQ密码,而是自己邮箱-账户-开启POP3/SMTP时的客户端授权码
# password: QQ邮箱客户端授权码
# properties:
# mail:
# smtp:
# # 需要验证登录名和密码
# auth: true
# starttls:
# # 需要TLS认证 保证发送邮件安全验证
# enable: true
# required: true
3. 任务类
这里演示几种常见的发邮件形式。
@Component
public class SendMailTask extends QuartzJobBean {
private static final Logger logger = LoggerFactory.getLogger(HelloTask.class);
@Autowired
public SendMailService sendMailService;
@Override
protected void executeInternal(JobExecutionContext context) throws JobExecutionException {
try {
logger.info("-------------开始发邮件了" + new Date() + "---------");
// 发送简单文本邮件
sendMailService.sendSimpleTextMail();
// 发送html格式的邮件
// sendMailService.sendHtmlMail();
// 发送带附件的邮件:图片、EXCEL、Word等附件
// sendMailService.sendAttachmentMail();
// 发送含有静态资源的邮件
// sendMailService.sendStaticResourceMail();
// 使用freemarker模板发送邮件
// sendMailService.sendFreemarkerMail();
logger.info("-------------已经完成邮件发送---------");
} catch (Exception e) {
logger.error("邮件发送错误:" + e);
}
}
}
4. 配置类
@Configuration
public class SendMailConfig {
@Bean
public JobDetail sendMailJobDetail() {
// 定义job
return JobBuilder.newJob(SendMailTask.class).withIdentity("sendMail").storeDurably().build();
}
@Bean
public CronTrigger sendMailByCornTrigger() {
// 定义调度器和触发器规则(每10s执行一次)
CronScheduleBuilder csb = CronScheduleBuilder.cronSchedule(String.format("0/10 * * * * ? *"))
.withMisfireHandlingInstructionDoNothing();
// 使用调度器调度触发器执行指定的job
return TriggerBuilder.newTrigger().forJob(sendMailJobDetail())
.withIdentity("sendMailCornTrigger").withDescription("cron类型触发器").withSchedule(csb).startNow().build();
}
}
4. 实现层的业务逻辑
让我的163邮箱定时给我的QQ邮箱发邮件信息
@Service
public class SendMailServiceImpl implements SendMailService {
// 发送邮件对象
@Autowired
private JavaMailSender javaMailSender;
// 我的163邮箱
@Value("${spring.mail.username}")
private String my163Mail;
// 我的QQ邮箱
private String myQQMail = "86******[email protected]";
// 邮件的主题和内容
private String subject = "中东部雨雪发展或扰春运 周中大风降温来袭";
private String simpleText = "中国天气网讯 预计今(28日)起三天," +
"中东部雨雪发展增多,有一次较明显降水过程,黄淮、江淮等地还可能迎来雨雪相态转换," +
"公众春运出行请注意交通安全。而且本周中还将有冷空气来袭,30日至2月1日,中东部大部气" +
"温下降4~8℃并伴有大风,需注意防风防寒。";
/**
* 发送简单文本邮件
*/
@Override
public void sendSimpleTextMail() {
// 设置邮件发送内容
SimpleMailMessage mailMessage = new SimpleMailMessage();
// 发件人: setFrom处必须填写自己的邮箱地址,否则会报553错误
mailMessage.setFrom(my163Mail);
// 收件人
mailMessage.setTo(myQQMail);
// 抄送收件人:网易邮箱要指定抄送收件人,不然会报 554(发送内容错误)
mailMessage.setCc(my163Mail);
// 主题
mailMessage.setSubject(subject);
// 内容
mailMessage.setText(simpleText);
try {
javaMailSender.send(mailMessage);
System.out.println("发送简单文本邮件成功,主题是:" + subject);
} catch (Exception e) {
System.out.println("-----发送简单文本邮件失败!-------" + e.toString());
e.printStackTrace();
}
}
}
三、测试一下
启动DemoApplication类,观察日志输出:
我的QQ邮箱收到的邮件:
抄送邮箱收到的邮件:
四、拓展一下
上面是发送简单文本邮件,还有其他形式的邮件发送,重点讲一下逻辑实现吧。
简单文本邮件发送用SimpleMailMessage对象的实例设置邮件参数即可完成发送功能,带有HTML格式,静态资源格式,带附件的格式发送邮件需要借助JavaMailSender对象的createMimeMessage()方法创建的实例作为发送对象,而设置邮件参数通过MimeMessageHelper对象完成。
MimeMessage mimeMessage = javaMailSender.createMimeMessage();
MimeMessageHelper messageHelper = new MimeMessageHelper(mimeMessage, true);
// 使用MimeMessageHelper设置邮件信息
messageHelper.setFrom(myQQMail);
messageHelper.setTo(myQQMail);
messageHelper.setCc(myQQMail);
messageHelper.setSubject(subject);
messageHelper.setText(htmlText, true);
javaMailSender.send(mimeMessage);
MimeMessage mimeMessage = javaMailSender.createMimeMessage();
MimeMessageHelper messageHelper = new MimeMessageHelper(mimeMessage, true);
// 使用MimeMessageHelper设置邮件信息
messageHelper.setFrom(myQQMail); //发件人
messageHelper.setTo(MrWangQQMail); // 收件人
messageHelper.setCc(my163Mail); // 抄送
messageHelper.setSubject(subject);
messageHelper.setText(htmlText, true);
// 指定附件的文件
FileSystemResource fsr = new FileSystemResource(new File(filePath1));
// 发送的附件
// String fileName = filePath.substring(filePath.lastIndexOf("/"));
messageHelper.addAttachment("截图.png", fsr);
javaMailSender.send(mimeMessage);
MimeMessage mimeMessage = javaMailSender.createMimeMessage();
try {
MimeMessageHelper messageHelper = new MimeMessageHelper(mimeMessage, true);
// 使用MimeMessageHelper设置邮件信息
messageHelper.setFrom(myQQMail);
messageHelper.setTo(myQQMail);
messageHelper.setCc(myQQMail);
messageHelper.setSubject(subject);
// html里要用cid写法指定图片
messageHelper.setText(staticResText, true);
// 指定发送的静态资源
FileSystemResource picture1 = new FileSystemResource(new File(filePath1));
FileSystemResource picture2 = new FileSystemResource(new File(filePath2));
// contentId对应html中的cid名称
messageHelper.addInline("mypicture", picture1);
messageHelper.addInline("分类", picture2);
javaMailSender.send(mimeMessage);
System.out.println("发送含有静态资源的邮件成功,主题是:" + subject);
} catch (Exception e) {
System.out.println("-----发送含有静态资源的邮件失败!-------" + e.toString());
e.printStackTrace();
}
最后说一下,整合过程中会遇到一些错误,我已经标注在代码或配置里了,动手实践一下会有更深的体会呦!