环境:
IDEA,SpringBoot,QQ邮箱开启smtp
pom导入依赖:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-mail</artifactId>
</dependency>
application.yml配置:
spring:
mail:
host: smtp.qq.com # 服务端
username: 123456789@qq.com # 发件人
password: xxxxxxxxxxxxx # 授权码,qq邮箱激活smtp时获得
properties:
mail:
smtp:
auth: true
starttls:
enable: true
required: true
default-encoding: UTF-8
创建发送邮件线程池:
/**
* @author YoonaLt
* @date 2019/12/09
* 异步发送邮件线程池
*/
@Configuration
public class MailExecutors {
@Bean("mailExecutor")
public ExecutorService getPool() {
ArrayBlockingQueue queue = new ArrayBlockingQueue(50);
return new ThreadPoolExecutor(7, 10,
100L, TimeUnit.SECONDS, queue, new MailThreadFactory("mailSend"));
}
/**
* 主要是为了命名线程,回溯的时候易找出
*/
static class MailThreadFactory implements ThreadFactory {
private static final AtomicInteger POOL_NUMBER = new AtomicInteger(1);
private final ThreadGroup group;
private final AtomicInteger threadNumber = new AtomicInteger(1);
private final String namePrefix;
MailThreadFactory(String name) {
SecurityManager s = System.getSecurityManager();
group = (s != null) ? s.getThreadGroup() :
Thread.currentThread().getThreadGroup();
namePrefix = name +
POOL_NUMBER.getAndIncrement() +
"-thread-";
}
@Override
public Thread newThread(Runnable r) {
Thread t = new Thread(group, r,
namePrefix + threadNumber.getAndIncrement(),
0);
if (t.isDaemon()) {
t.setDaemon(false);
}
if (t.getPriority() != Thread.NORM_PRIORITY) {
t.setPriority(Thread.NORM_PRIORITY);
}
return t;
}
}
}
自定义相关实体类:
public class MailEnclosure {
private String fileName;
private String path;
public String getFileName() {
return fileName;
}
public void setFileName(String fileName) {
this.fileName = fileName == null ? null : fileName.trim();
}
public String getPath() {
return path;
}
public void setPath(String path) {
this.path = path == null ? null : path.trim();
}
public MailEnclosure(String fileName, String path) {
super();
this.fileName = fileName;
this.path = path;
}
}
public class MailResource {
private String cid;
private String path;
public String getCid() {
return cid;
}
public void setCid(String cid) {
this.cid = cid == null ? null : cid.trim();
}
public String getPath() {
return path;
}
public void setPath(String path) {
this.path = path == null ? null : path.trim();
}
public MailResource(String cid, String path) {
super();
this.cid = cid;
this.path = path;
}
}
创建发送服务类:
/**
* @author YoonaLt
* @date 2019/12/09
* 邮件发送服务配置。可能被收件方标记为垃圾邮件,需要收件方添加白名单。
* 此示例默认异步调用全部成功,实际上可以通过 Future 接口的 isDone() 方法来判断异步调用是否执行。
*/
@Service
public class MailService {
private Logger logger = LoggerFactory.getLogger(this.getClass());
@Autowired
private JavaMailSender javaMailSender;
@Value("${spring.mail.username}")
private String from;
/**
* 发送简单文本邮件
*
* @param to 收件人
* @param subject 主题
* @param content 内容
*/
@Async("mailExecutor")
public void sendSimpleMail(String to, String subject, String content) {
SimpleMailMessage simpleMailMessage = new SimpleMailMessage();
simpleMailMessage.setFrom(from);
simpleMailMessage.setTo(to);
simpleMailMessage.setSubject(subject);
simpleMailMessage.setText(content);
try {
javaMailSender.send(simpleMailMessage);
logger.info("向 " + to + " 发送邮件 " + subject + " 成功");
} catch (Exception e) {
logger.info("向 " + to + " 发送邮件 " + subject + " 失败,失败原因是");
e.printStackTrace();
}
}
/**
* 发送带有图片或附件的html格式邮件
*
* @param to 收件人
* @param subject 主题
* @param content 内容
* @param mailResourceList 静态资源
* @param mailEnclosureList 附件
*/
@Async("mailExecutor")
public void sendMimeMail(String to, String subject, String content, List<MailResource> mailResourceList, List<MailEnclosure> mailEnclosureList) {
MimeMessage mimeMessage = javaMailSender.createMimeMessage();
try {
MimeMessageHelper mimeMessageHelper = new MimeMessageHelper(mimeMessage, true);
mimeMessageHelper.setTo(to);
mimeMessageHelper.setFrom(from);
mimeMessageHelper.setText(content, true);
mimeMessageHelper.setSubject(subject);
if (mailResourceList != null) {
for (MailResource m : mailResourceList) {
FileSystemResource file = new FileSystemResource(new File(m.getPath()));
mimeMessageHelper.addInline(m.getCid(), file);
}
}
if (mailEnclosureList != null) {
for (MailEnclosure m : mailEnclosureList) {
FileSystemResource file = new FileSystemResource(new File(m.getPath()));
mimeMessageHelper.addAttachment(m.getFileName(), file);
}
}
javaMailSender.send(mimeMessage);
logger.info("向 " + to + " 发送邮件 " + subject + " 成功");
} catch (MessagingException e) {
logger.info("向 " + to + " 发送邮件 " + subject + " 失败,失败原因是");
e.printStackTrace();
}
}
}
启动类加注解: @EnableAsync 配合方法 @Async 注解实现异步发送邮件的功能.
一个简单的测试方法:
@GetMapping(value = "send")
public void sendMail() {
String to = "987654321@qq.com";
String subject = "带附件的html邮件";
String simpleContent = "简单邮件";
String htmlContent = " <font color=\"red\">发送的html邮件</font>\r\n";
String pictureContent = "<img src=\"cid:Evelynn\"/> " +
"<img src=\"cid:Ahri\"/> " +
" <font color=\"red\">发送带图片的html</font>\r\n";
String template =
"<!DOCTYPE html>\r\n" +
"<html>\r\n" +
"<head>\r\n" +
"<meta charset=\"UTF-8\">\r\n" +
"<title>标题</title>\r\n" +
"</head>\r\n" +
"<body>\r\n" +
htmlContent +
"</body>\r\n" +
"</html>";
List<MailResource> mailResourceList = new ArrayList<>();
List<MailEnclosure> mailEnclosureList = new ArrayList<>();
String path = "D:\\YoonaLt\\mail\\src\\main\\resources\\";
MailResource resource1 = new MailResource("Evelynn", path + "Evelynn.jpg");
MailResource resource2 = new MailResource("Ahri", path + "Ahri.jpg");
MailEnclosure mailEnclosure = new MailEnclosure("附件名称.jpg", path + "Ahri.jpg");
mailEnclosureList.add(mailEnclosure);
mailService.sendMimeMail(to, subject, template, null, mailEnclosureList);
}
由于本人水平有限,难免有疏漏与错误之处,谢谢指正: