标题spring boot 实现邮件发送并支持附件和添加图片
在 Spring Boot 中实现异步邮件发送功能,支持自定义主题、发送文件、自定义内容以及群发,可以通过以下步骤完成。可以使用Transport来处理邮件发送,并结合 Spring 的异步功能注解@Async来实现异步发送。
1 引入依赖
<dependency>
<groupId>com.sun.mail</groupId>
<artifactId>javax.mail</artifactId>
<version>1.6.2</version>
</dependency>
配置邮件发送属性
#企业微信发邮件配置
mail:
transport:
protocol: ssl
smtp:
host: smtp.exmail.qq.com # 企业微信的host
port: 465 #邮件服务器的端口号
auth: true
ssl:
enable: true
from: xxxxx # 发送邮件
enable: true
account: xxxxx # 用于身份验证的邮箱地址
password: xxxxx #用于身份验证的邮箱地址 密码
需要注意的是如果是qq邮箱,host应该替换为:smtp.qq.com ,port 也不是465而是587,且password不是对应邮箱的密码,而是一个随机生成的授权码。
3 创建邮件服务
package com.gotion.framework.email;
import java.util.List;
/**
* 邮件发送Service
* @Description
* @Author
**/
public interface ISendEmailService {
/**
* 发送邮件
* @param fromAliasName 别名
* @param to 发送目标
* @param subject 主题
* @param content 内容
* @param attachFileList 附件
*/
void send(String fromAliasName,String to,String subject,String content, List<String> attachFileList);
}
package com.gotion.framework.email.impl;
import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
import com.gotion.framework.email.ISendEmailService;
import com.sun.mail.util.MailSSLSocketFactory;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;
import javax.mail.Authenticator;
import javax.mail.Message;
import javax.mail.Multipart;
import javax.mail.PasswordAuthentication;
import javax.mail.Session;
import javax.mail.Transport;
import javax.mail.internet.InternetAddress;
import javax.mail.internet.MimeBodyPart;
import javax.mail.internet.MimeMessage;
import javax.mail.internet.MimeMultipart;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.security.GeneralSecurityException;
import java.util.Date;
import java.util.List;
import java.util.Properties;
/**
* 邮件发送工具类
* 注:腾讯企业微信邮箱需要用SSL方式发送
* @author
*/
@Slf4j
@Service
@ConditionalOnProperty("mail")
public class SendEmailServiceImpl implements ISendEmailService {
@Value("${mail.account}")
private String account ;
/**
* 登录密码
*/
@Value("${mail.password}")
private String password;
/**
* 发信协议
*/
@Value("${mail.transport.protocol}")
private String protocol;
/**
* 邮件服务器地址
*/
@Value("${mail.smtp.host}")
private String host;
/**
* 邮件发送方
*/
@Value("${mail.smtp.from}")
private String from;
/**
* 发信端口
*/
@Value("${mail.smtp.port}")
private String port ;
/**
* 发信端口
*/
@Value("${mail.smtp.auth}")
private String auth ;
@Value("${mail.smtp.ssl.enable}")
private String sslEnable ;
/**
* 发送邮件
*/
@Override
@Async
public void send(String fromAliasName, String to, String subject, String content, List<String> attachFileList) {
// 设置邮件属性
Properties prop = new Properties();
prop.setProperty("mail.transport.protocol", protocol);
prop.setProperty("mail.smtp.host", host);
prop.setProperty("mail.smtp.port", port);
prop.setProperty("mail.smtp.auth", auth);
prop.setProperty("mail.smtp.ssl.protocols", "TLSv1.2");
prop.setProperty("mail.smtp.from", from);
MailSSLSocketFactory sslSocketFactory = null;
try {
sslSocketFactory = new MailSSLSocketFactory();
sslSocketFactory.setTrustAllHosts(true);
} catch (GeneralSecurityException e) {
log.error("MailSSLSocketFactory set fail",e);
}
if (sslSocketFactory == null) {
log.error("Failed to enable MailSSLSocketFactory");
} else {
prop.put("mail.smtp.ssl.enable",sslEnable);
prop.put("mail.smtp.ssl.socketFactory", sslSocketFactory);
// 创建邮件会话(注意,如果要在一个进程中切换多个邮箱账号发信,应该用 Session.getInstance)
Session session = Session.getDefaultInstance(prop, new MyAuthenticator(account, password));
try {
MimeMessage mimeMessage = new MimeMessage(session);
// 设置发件人别名(如果未设置别名就默认为发件人邮箱)
if (fromAliasName != null && !fromAliasName.trim().isEmpty()) {
mimeMessage.setFrom(new InternetAddress(account, fromAliasName));
}
// 设置主题和收件人、发信时间等信息
mimeMessage.addRecipient(Message.RecipientType.TO, new InternetAddress(to));
mimeMessage.setSubject(subject);
mimeMessage.setSentDate(new Date());
// 如果有附件信息,则添加附件
Multipart multipart = new MimeMultipart();
MimeBodyPart body = new MimeBodyPart();
body.setContent(content, "text/html; charset=UTF-8");
multipart.addBodyPart(body);
// 添加所有附件(添加时判断文件是否存在)
if (CollectionUtils.isNotEmpty(attachFileList)){
for(String filePath : attachFileList){
if(Files.exists(Paths.get(filePath))){
MimeBodyPart tempBodyPart = new MimeBodyPart();
tempBodyPart.attachFile(filePath);
multipart.addBodyPart(tempBodyPart);
}
}
}
mimeMessage.setContent(multipart);
// 开始发信
mimeMessage.saveChanges();
Transport.send(mimeMessage);
}catch (Exception e) {
log.error("Fail to send email",e);
}
}
}
/**
* 认证信息
*/
static class MyAuthenticator extends Authenticator {
/**
* 用户名
*/
String username = null;
/**
* 密码
*/
String password = null;
/**
* 构造器
*
* @param username 用户名
* @param password 密码
*/
public MyAuthenticator(String username, String password) {
this.username = username;
this.password = password;
}
@Override
protected PasswordAuthentication getPasswordAuthentication() {
return new PasswordAuthentication(username, password);
}
}
}
4. 启用异步功能
package com.gotion;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration;
import org.springframework.scheduling.annotation.EnableAsync;
/**
* 启动程序
*
*/
@EnableAsync
@SpringBootApplication(exclude = { DataSourceAutoConfiguration.class })
public class GotionApplication
{
public static void main(String[] args)
{
SpringApplication.run(GotionApplication.class, args);
}
}
5. 使用邮件服务
import java.util.List;
@RestController
@Slf4j
public class TestEmailSendController {
@Autowired(required = false)
private ISendEmailService sendEmailService;
@PostMapping("/example/send/email")
public AjaxResult testSendEmail(@RequestParam(required = false) String fromAliasName,
@RequestParam(required = false) String to,
@RequestParam(required = false) String subject,
@RequestParam(required = false) String content,
@RequestParam(required = false) String attachFiles) {
List<String> attachFileList = Arrays.stream(attachFiles.split(",")).toList();
sendEmailService.send(fromAliasName,to,subject,content,attachFileList);
return AjaxResult.success();
}
}
6. 使用邮件服务