
邮件服务概述
邮件服务在互联网早期已经出现,发送与接收的过程如下:
发件人使用SMTP协议传输邮件到邮件A服务器
邮件服务器A根据邮件中指定的接收者投递邮件到对应的邮件服务器B
收件人使用POP3协议从邮件服务器B接收邮件
SMTP(Simple Mail Transfer Protocol)是电子邮件(Email)传输的互联网标准,定义在RFC5321,默认使用25端口。
POP3(Post Office Protocol -Version 3)主要用于支持使用客户端远程管理所在服务器上的电子邮件,定义在RFC1939,为POP3协议的第三版。
这两个协议属于TCP/IP协议层的应用层协议,运行在TCP层。
发送邮件的需求比较常见,如注册用户激活、密码找回、事件通知等。SUN公司给广大Java开发人员提供了用于邮件发送和接收的开源类库JavaMail,支持常用的邮件协议,如SMTP、POP3、IMAP等。开发人员使用JavaMail编写邮件程序时,不需要考虑底层通信细节,只需要关注逻辑层面。JavaMail(仅支持JDK1.4+)可以发送各种复杂MIME格式的邮件内容。Spring提供了JavaMailSender接口实现邮件发送,在SpringBoot的Starter模块中进行了集成。
发送邮件实例
在使用邮箱发送邮件之前,需要先设置邮箱账户名和开启协议。


开启服务后, 根据操作生成对应的授权码,对生成的授权码信息进行保存,作为邮件发送用户密码使用。
引入SpringBootMail依赖
<!--引入发送邮件依赖--><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-mail</artifactId></dependency>
配置发送邮件相关配置信息
#配置发送邮件相关信息#邮件服务器地址spring.mail.host=smtp.qq.com#邮件服务器端口号(465或587)spring.mail.port=465#邮箱地址作为用户名spring.mail.username=邮箱地址#授权码作为邮箱密码spring.mail.password=授权码#默认编码集spring.mail.default-encoding=UTF-8#设置SSL连接spring.mail.properties.mail.smtp.socketFactory.class=javax.net.ssl.SSLSocketFactory#开启调试spring.mail.properties.mail.debug=true
邮件类型对应实体
简单文本邮件
public class SimpleEmail {private String fromEmail;//发送邮箱地址private String toEmail;//接收邮箱地址private String ccList;//抄送人private String subject;//邮件主题private String content;//邮件内容}
附件邮件
public class FileEmail {private String fromEmail;//发送邮箱地址private String toEmail;//接收邮箱地址private String subject;//邮件主题private String content;//邮件内容private File fileInfo;//附件文件}
图片邮件
public class ImageEmail {private String fromEmail;//发送邮件地址private String toEmail;//接收邮件地址private String subject;//邮件主题private String content;//邮件内容private String[] srcPath;//图片资源路径绝对地址数组private String[] resIds;//资源Id数组,在image元素中通过cid:id显示(id与数组元素内容一致)}
邮件逻辑层
@Componentpublic class EmailService {@AutowiredJavaMailSender mailSender;/*** 发送简单邮件* @param simpleEmail:简单邮件实体*/public void sendSimpleMail(SimpleEmail simpleEmail){//简单邮件消息SimpleMailMessage simpleMailMessage=new SimpleMailMessage();simpleMailMessage.setFrom(simpleEmail.getFromEmail());simpleMailMessage.setTo(simpleEmail.getToEmail());simpleMailMessage.setCc(simpleEmail.getCcList());simpleMailMessage.setSubject(simpleEmail.getSubject());simpleMailMessage.setText(simpleEmail.getContent());mailSender.send(simpleMailMessage);}/*** 发送带图片邮件* @param imageEmail:图片邮件实体*/public void sendImageMail(ImageEmail imageEmail){if(imageEmail.getSrcPath().length!=imageEmail.getResIds().length){System.out.println("图片资源与resIds元素数量不一致,发送失败");}try {MimeMessage mimeMessage=mailSender.createMimeMessage();MimeMessageHelper mimeMessageHelper=new MimeMessageHelper(mimeMessage,true);mimeMessageHelper.setFrom(imageEmail.getFromEmail());mimeMessageHelper.setTo(imageEmail.getToEmail());mimeMessageHelper.setSubject(imageEmail.getSubject());mimeMessageHelper.setText(imageEmail.getContent(),true);for(int i=0;i<imageEmail.getSrcPath().length;i++){//根据图片路径构建静态资源FileSystemResource systemResource=new FileSystemResource(new File(imageEmail.getSrcPath()[i]));//将静态资源加入邮件对象mimeMessageHelper.addInline(imageEmail.getSrcPath()[i],systemResource);}mailSender.send(mimeMessage);}catch (MessagingException ex){System.out.println("发送失败");}}/*** 发送附件邮件* @param fileEmail:附件邮件*/public void sendFileEmail(FileEmail fileEmail){if(fileEmail.getFileInfo()==null){System.out.println("未上传附件文件,发送失败");}try {MimeMessage fileMessage=mailSender.createMimeMessage();MimeMessageHelper fileHelper=new MimeMessageHelper(fileMessage,true);fileHelper.setFrom(fileEmail.getFromEmail());fileHelper.setTo(fileEmail.getToEmail());fileHelper.setSubject(fileEmail.getSubject());fileHelper.setText(fileEmail.getContent());//添加附件(文件名作为附件名)fileHelper.addAttachment(fileEmail.getFileInfo().getName(),fileEmail.getFileInfo());}catch (MessagingException ex){ex.printStackTrace();}}}
发送邮件测试
@RunWith(SpringJUnit4ClassRunner.class)@SpringBootTestpublic class SendMailTest {@Autowiredprivate EmailService emailService;@Testpublic void sendSimpleEmail(){SimpleEmail simpleEmail=new SimpleEmail();simpleEmail.setFromEmail(fromEmail);simpleEmail.setToEmail(toEmail);simpleEmail.setSubject("文本邮件测试");simpleEmail.setCcList(ccEmail);simpleEmail.setContent("SpringBoot发送简单文本邮件"+new Date().toString());emailService.sendSimpleMail(simpleEmail);}@Testpublic void sendImageEmail(){ImageEmail imageEmail=new ImageEmail();imageEmail.setToEmail(fromEmail);imageEmail.setFromEmail(toEmail);imageEmail.setSubject("图片邮件测试");String content="<div>SpringBoot发送图片邮件测试" +"<div><img src=\\'cid:\" + mybatis + \"\\' ></div>" +"<div><img src=\\'cid:\" + springboot + \"\\' ></div>" +"<div><img src=\\'cid:\" + rocketmq + \"\\' ></div>" +"</div>";imageEmail.setContent(content);String[] imageUrl=new String[]{"C:\\Users\\Admin\\Desktop\\mybatis.png","C:\\Users\\Admin\\Desktop\\springboot.jpg","C:\\Users\\Admin\\Desktop\\rocketmq.jpg"};String[] resIds=new String[]{"mybatis","springboot","rocketmq"};imageEmail.setSrcPath(imageUrl);imageEmail.setResIds(resIds);emailService.sendImageMail(imageEmail);}@Testpublic void sendFileEmail(){FileEmail fileEmail=new FileEmail();fileEmail.setFromEmail(fromEmail);fileEmail.setToEmail(toEmail);fileEmail.setSubject("SpringBoot发送附件邮件");fileEmail.setContent("SpringBoot发送包含附件邮件");fileEmail.setFileInfo(new File(filePath));emailService.sendFileEmail(fileEmail);}}
使用定时任务发送邮件
package com.springboot.demo.job;import com.springboot.demo.sendMail.SimpleEmail;import com.springboot.demo.sendMail.service.EmailService;import org.quartz.JobExecutionContext;import org.quartz.JobExecutionException;import org.springframework.beans.factory.annotation.Autowired;import org.springframework.scheduling.quartz.QuartzJobBean;import org.springframework.stereotype.Component;import java.util.Date;/*** 发送文本文件定时任务*/@Componentpublic class SendSimpleEmailJob extends QuartzJobBean {private SimpleEmail simpleEmail;@Autowiredprivate EmailService emailService;public void setSimpleEmail(SimpleEmail simpleEmail) {this.simpleEmail = simpleEmail;}@Overrideprotected void executeInternal(JobExecutionContext jobExecutionContext) throws JobExecutionException {emailService.sendSimpleMail(this.simpleEmail);}}
package com.springboot.demo.job;import com.springboot.demo.sendMail.FileEmail;import com.springboot.demo.sendMail.service.EmailService;import org.quartz.JobExecutionContext;import org.quartz.JobExecutionException;import org.springframework.beans.factory.annotation.Autowired;import org.springframework.scheduling.quartz.QuartzJobBean;import org.springframework.stereotype.Component;/*** 发送附件邮件定时任务*/@Componentpublic class SendFileEmailJob extends QuartzJobBean {private FileEmail fileEmail;@Autowiredprivate EmailService emailService;public void setFileEmail(FileEmail fileEmail) {this.fileEmail = fileEmail;}@Overrideprotected void executeInternal(JobExecutionContext jobExecutionContext) throws JobExecutionException {emailService.sendFileEmail(fileEmail);}}
定时任务Quartz配置
package com.springboot.demo.job.config;import com.springboot.demo.job.SendFileEmailJob;import com.springboot.demo.job.SendSimpleEmailJob;import com.springboot.demo.sendMail.FileEmail;import com.springboot.demo.sendMail.SimpleEmail;import org.quartz.CronTrigger;import org.quartz.JobDataMap;import org.quartz.SimpleTrigger;import org.springframework.context.annotation.Bean;import org.springframework.context.annotation.Configuration;import org.springframework.scheduling.quartz.*;import java.io.File;import java.util.Date;@Configurationpublic class QuartzConfig {/*** 获取发送简易文本邮件定时任务* @return 发送简易文本邮件定时任务实例*/@BeanJobDetailFactoryBean getSimpleEmailJobDetail(){JobDetailFactoryBean simpleEmailJob=new JobDetailFactoryBean();simpleEmailJob.setJobClass(SendSimpleEmailJob.class);SimpleEmail simpleEmail=new SimpleEmail();simpleEmail.setFromEmail("99967706@qq.com");simpleEmail.setToEmail("596648433@qq.com");simpleEmail.setSubject("定时任务发送文本邮件测试");simpleEmail.setCcList("99967706@qq.com");simpleEmail.setContent("SpringBoot定时任务发送简单文本邮件"+new Date().toString());//设置参数JobDataMap dataMap=new JobDataMap();dataMap.put("simpleEmail",simpleEmail);simpleEmailJob.setJobDataMap(dataMap);simpleEmailJob.setDurability(true);return simpleEmailJob;}/*** 获取发送附件邮件定时任务* @return 发送附件邮件定时任务实例*/@BeanJobDetailFactoryBean getFileEmailJobDetail(){JobDetailFactoryBean fileEmailJob=new JobDetailFactoryBean();fileEmailJob.setJobClass(SendFileEmailJob.class);FileEmail fileEmail=new FileEmail();fileEmail.setFromEmail("99967706@qq.com");fileEmail.setToEmail("596648433@qq.com");fileEmail.setSubject("SpringBoot定时任务发送附件邮件");fileEmail.setContent("SpringBoot定时任务发送包含附件邮件");fileEmail.setFileInfo(new File("C:\\Users\\Admin\\Desktop\\mybatis.png"));//设置参数JobDataMap dataMap=new JobDataMap();dataMap.put("fileEmail",fileEmail);fileEmailJob.setJobDataMap(dataMap);fileEmailJob.setDurability(true);return fileEmailJob;}/*** 简易触发器* @return 简易触发器实例*/@BeanSimpleTriggerFactoryBean getSimpleTrigger(){//初始化简易触发器SimpleTriggerFactoryBean simpleTriggerBean=new SimpleTriggerFactoryBean();//为触发器绑定定时任务simpleTriggerBean.setJobDetail(getSimpleEmailJobDetail().getObject());//设置定时任务执行次数simpleTriggerBean.setRepeatCount(1);//定时任务初始化执行延迟时间simpleTriggerBean.setStartDelay(1000);//定时任务执行时间间隔simpleTriggerBean.setRepeatInterval(2000);return simpleTriggerBean;}/*** Crom表达式触发器* @return cron表达式触发器实例*/@BeanCronTriggerFactoryBean getCronTrigger(){//初始化Cron表达式触发器CronTriggerFactoryBean cronTrigger=new CronTriggerFactoryBean();//触发器绑定定时任务cronTrigger.setJobDetail(getFileEmailJobDetail().getObject());//设置cron表达式(每天22:30自动执行定时任务)cronTrigger.setCronExpression("0 30 22 * * ?");return cronTrigger;}/*** 创建定时任务工厂并设置触发器* @return 定时任务工厂*/@BeanSchedulerFactoryBean getSchedulerFactory(){//初始化定时任务工厂实例SchedulerFactoryBean schedulerFactory=new SchedulerFactoryBean();//获取绑定定时任务后的触发器SimpleTrigger simpleTrigger=getSimpleTrigger().getObject();CronTrigger cronTrigger=getCronTrigger().getObject();//为定时任务工厂设置触发器schedulerFactory.setTriggers(simpleTrigger,cronTrigger);//返回定时任务工厂return schedulerFactory;}}




