之前遇到了一个基于SpringBoot项目实现发送邮件的功能,所以当时在开发功能之前写了一个基于SpringBoot2.x实现发送邮件的demo,之前在论坛中看有人问SpringBoot应该怎么实现正文是html模板并且带有附件的邮件发送功能。之前写的demo正好符合这个需求,所以在这里把代码进行一下分享。
话不多说直接上代码
spring:
mail:
#smtp服务地址
host: smtp.qq.com
#邮箱账号
username: [email protected]
#邮箱密码或者授权码(不同的邮箱不一样QQ邮箱是授权码,但是有的邮箱也可以直接使用密码)
password: xxxxxxxxxxxx
properties:
mail:
smtp:
auth: true
starttls:
enable: true
required: true
default-encoding: UTF-8
public interface MailService {
/**
* 发送邮件
* @param entity
*/
void sendMail(MailEntity entity);
/**
* 检验MailEntity是否合法
* @param entity
* @return
*/
boolean checkMailEntity(MailEntity entity);
}
import lombok.Builder;
import lombok.Getter;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.core.io.ByteArrayResource;
import org.springframework.core.io.InputStreamSource;
import org.springframework.util.CollectionUtils;
import java.io.*;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.LinkedHashSet;
import java.util.Set;
/**
* 邮件实体
*/
@Slf4j
public class MailEntity {
/**
* 收件人
*/
private Set<String> mialTos = new LinkedHashSet<>();
/**
* 邮件密送人
*/
private Set<String> mailBcc = new LinkedHashSet<>();
/**
* 邮件抄送人
*/
private Set<String> mailCc = new LinkedHashSet<>();
/**
* 邮件附件
*/
private Set<MailAttachment> attachments = new LinkedHashSet<>();
/**
* 是否存在附件
*/
private boolean hasAttachments = false;
/**
* 邮件主题
*/
private String mailSubject;
/**
* 邮件内容
*/
private String mailContent;
/**
* html格式邮件
*/
private boolean html = false;
/**
* 邮件发件人
*/
private String mailFrom;
/**
* 得到收件人
* @return
*/
public String[] getMialTos() {
return asArray(this.mialTos);
}
/**
* 设置收件人
* @param mailTos 收件人邮箱地址
*/
public void setMailTos(String... mailTos) {
this.mialTos = asSet(mailTos);
}
/**
* 得到密送人
* @return
*/
public String[] getMailBcc() {
return asArray(this.mailBcc);
}
/**
* 设置密送人
* @param mailBcc 密送人邮箱地址
*/
public void setMailBcc(String... mailBcc) {
this.mailBcc = asSet(mailBcc);
}
/**
* 得到抄送人
* @return
*/
public String[] getMailCc() {
return asArray(this.mailCc);
}
/**
* 设置抄送人
* @param mailCc 抄送人邮箱地址
*/
public void setMailCc(String... mailCc) {
this.mailCc = asSet(mailCc);
}
/**
* 得到邮件主题
* @return
*/
public String getMailSubject() {
return mailSubject;
}
/**
* 设置邮件主题
* @param mailSubject 邮件主题
*/
public void setMailSubject(String mailSubject) {
this.mailSubject = mailSubject;
}
/**
* 得到邮件内容
* @return
*/
public String getMailContent() {
return mailContent;
}
/**
* 设置邮件内容
* @param mailContent
*/
public void setMailContent(String mailContent) {
this.mailContent = mailContent;
}
/**
* 设置邮件正文是否是Html形式
* @param html
*/
public void setHtmlContant(boolean html) {
this.html = html;
}
/**
* 判断邮件正文是否是Html形式
* @return
*/
public boolean isHtmlContant() {
return this.html;
}
/**
* 得到邮件附件集合
* @return
*/
public Set<MailAttachment> getAttachments() {
return attachments;
}
/**
* 判断是否包含附件
* @return
*/
public boolean isHasAttachments() {
return hasAttachments;
}
/**
* 设置发件人
* @param mailFrom 发件人邮箱地址
*/
public void setMailFrom(String mailFrom) {
this.mailFrom = mailFrom;
}
/**
* 得到发件人邮箱地址
* @return
*/
public String getMailFrom() {
return mailFrom;
}
/**
* 将Set转为String[]
* @param arg Set
* @return
*/
private String[] asArray(Set<String> arg){
return CollectionUtils.isEmpty(arg) ? null : arg.toArray(new String[arg.size()]);
}
/**
* 将String[]转为Set
* @param arg String[]
* @return
*/
private Set<String> asSet(String... arg){
Set<String> set = new LinkedHashSet<>();
if(null == arg || arg.length == 0){
return set;
}
set = new LinkedHashSet<>(new ArrayList<>(Arrays.asList(arg)));
return set;
}
/**
* 添加附件
* @param attachmentName 附件名
* @param attachment 附件输入流
*/
public void addAttachment(String attachmentName,InputStream attachment){
if(StringUtils.isBlank(attachmentName)
|| null == attachment) {
log.error("无效的资源,参数attachmentName或attachment为空");
return;
}
BufferedInputStream buffer = new BufferedInputStream(attachment);
byte[] bt = null;
try {
bt = new byte[buffer.available()];
buffer.read(bt);
} catch (IOException e) {
log.error("邮件附件读取异常",e);
} finally {
try {
attachment.close();
buffer.close();
} catch (IOException e) {
log.error("InputStream关闭异常",e);
}
}
if(null != bt) {
addAttachment(attachmentName, bt);
}
}
/**
* 添加附件
* @param attachmentName 附件名
* @param attachment 附件文件对象
*/
public void addAttachment(String attachmentName, File attachment){
if(null == attachment || !attachment.exists()){
log.error("无效的资源,参数attachment为空或不存在");
return;
}
InputStream inputStream = null;
try {
inputStream = new FileInputStream(attachment);
addAttachment(attachmentName,inputStream);
} catch (FileNotFoundException e) {
log.error("文件未找到异常",e);
} finally {
try {
inputStream.close();
} catch (IOException e) {
log.error("FileInputStream关闭异常",e);
}
}
}
/**
* 添加附件
* @param attachmentName 附件名
* @param attachmentPath 附件路径
*/
public void addAttachment(String attachmentName,String attachmentPath){
if(StringUtils.isBlank(attachmentPath)){
log.error("无效的资源,参数attachmentPath为空");
return;
}
File attachment = new File(attachmentPath);
addAttachment(attachmentName,attachment);
}
/**
* 添加附件
* @param attachmentName 附件名
* @param attachmentByteArray 附件字节数组
*/
public void addAttachment(String attachmentName,byte[] attachmentByteArray){
if(null == attachmentByteArray || attachmentByteArray.length == 0){
log.error("无效的资源,参数attachmentByteArray为空");
}
this.attachments.add(MailAttachment.builder()
.attachmentName(attachmentName)
.attachment(new ByteArrayResource(attachmentByteArray)).build());
this.hasAttachments = true;
}
/**
* 邮件附件实体
*/
@Builder
@Getter
public static final class MailAttachment {
private String attachmentName;
private InputStreamSource attachment;
}
}
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.env.Environment;
import org.springframework.mail.javamail.JavaMailSender;
import org.springframework.mail.javamail.MimeMessageHelper;
import org.springframework.stereotype.Service;
import javax.mail.MessagingException;
import javax.mail.internet.MimeMessage;
import java.util.Set;
@Service
@Slf4j
public class MailServiceImpl implements MailService {
@Autowired
private JavaMailSender mailSender;
@Autowired
private Environment environment;
@Override
public void sendMail(MailEntity entity) {
if(!checkMailEntity(entity)){
log.info("entity不合法,邮件发送失败");
}
MimeMessage mimeMessage = createNewMimeMessage(entity);
mailSender.send(mimeMessage);
}
@Override
public boolean checkMailEntity(MailEntity entity) {
if(null == entity){
log.info("参数MailEntity为空");
return false;
} else if(isEmpty(entity.getMialTos())){
log.info("收件人为空");
return false;
} else if(StringUtils.isBlank(entity.getMailSubject())){
log.info("邮件主题为空");
return false;
}
return true;
}
/**
* 创建邮件消息对象{@link MimeMessage}
* @param entity
* @return
*/
private MimeMessage createNewMimeMessage(MailEntity entity){
MimeMessage mimeMessage = mailSender.createMimeMessage();
final MimeMessageHelper[] helper = new MimeMessageHelper[1];
try {
//发件人为空默认读取Application.yml中配置的邮箱
if(StringUtils.isBlank(entity.getMailFrom())){
entity.setMailFrom(environment.getProperty("spring.mail.username"));
}
//判断邮件是否包含附件
if(entity.isHasAttachments()){
//如果邮件包含附件需要使用带有 boolean multipart 参数的构造函数并且指定为true
helper[0] = new MimeMessageHelper(mimeMessage,true);
} else {
helper[0] = new MimeMessageHelper(mimeMessage);
}
//设置邮件的收件人
helper[0].setTo(entity.getMialTos());
//设置抄送人
if(null != entity.getMailCc()){
helper[0].setCc(entity.getMailCc());
}
//设置密送人
if(null != entity.getMailBcc()){
helper[0].setBcc(entity.getMailBcc());
}
//设置邮件主题
helper[0].setSubject(entity.getMailSubject());
//邮件正文是否是html格式
if(entity.isHtmlContant()){
helper[0].setText(entity.getMailContent(),true);
} else{
helper[0].setText(entity.getMailContent(),false);
}
//设置发件人
helper[0].setFrom(entity.getMailFrom());
//设置附件
if(entity.isHasAttachments()) {
Set<MailEntity.MailAttachment> attachments = entity.getAttachments();
attachments.forEach((attachment) -> {
try {
helper[0].addAttachment(attachment.getAttachmentName(),attachment.getAttachment());
} catch (MessagingException e) {
log.error("设置邮件附件异常",e);
}
});
}
} catch (MessagingException e) {
log.error("发送邮件异常",e);
}
return mimeMessage;
}
/**
* 判断数组是否为空
* @param arr
* @param
* @return
*/
private <T> boolean isEmpty(T[] arr){
if(null == arr || arr.length == 0){
return true;
}
return false;
}
}
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.event.annotation.BeforeTestMethod;
import org.springframework.test.web.servlet.MockMvc;
import org.springframework.test.web.servlet.setup.MockMvcBuilders;
import org.springframework.web.context.WebApplicationContext;
@SpringBootTest
class SpringbootApplicationTests {
@Autowired
protected WebApplicationContext webApplicationContext;
@Autowired
private MailService mailService;
protected MockMvc mockMvc;
@BeforeTestMethod
public void init() {
mockMvc = MockMvcBuilders.webAppContextSetup(webApplicationContext).build();
}
@Test
void testSendMail(){
MailEntity mailEntity = new MailEntity();
mailEntity.setMailTos("[email protected]");
mailEntity.setMailSubject("xxx test mail"+System.currentTimeMillis());
mailEntity.setMailContent("这是一个测试邮件
");
mailEntity.setHtmlContant(true);
mailEntity.addAttachment("001.jpg","C:\\Users\\92346\\Desktop\\6d468373gw1eqhb4zxjtej21hc0u0tsu.jpg");
mailService.sendMail(mailEntity);
}
}