省略部分其他getter与setter方法
import com.springcloud.my.config.MailFor163Config;
import com.springcloud.my.service.MailSendTo163Service;
import com.springcloud.my.utils.ContentTypeEnum;
import com.springcloud.my.utils.SetVelocityPro;
import lombok.extern.slf4j.Slf4j;
import org.apache.velocity.Template;
import org.apache.velocity.VelocityContext;
import org.apache.velocity.app.VelocityEngine;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.io.FileSystemResource;
import org.springframework.mail.javamail.JavaMailSenderImpl;
import org.springframework.mail.javamail.MimeMessageHelper;
import org.springframework.stereotype.Service;
import org.springframework.util.ResourceUtils;
import javax.activation.DataHandler;
import javax.activation.DataSource;
import javax.activation.FileDataSource;
import javax.mail.*;
import javax.mail.internet.*;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.StringWriter;
import java.io.UnsupportedEncodingException;
import java.util.Date;
import java.util.Map;
import java.util.Properties;
/**
* 发送邮件到163邮箱服务
*
* @Author Administrator
* @Date 2020/6/26
*/
@Slf4j
@Service
public class MailSendTo163ServiceImpl implements MailSendTo163Service {
@Autowired
JavaMailSenderImpl javaMailSender;
@Autowired
MailFor163Config mailFor163Config;
private DataHandler getDataHandlerByPath(String resourceLocation) throws FileNotFoundException {
File file = ResourceUtils.getFile(resourceLocation);
DataSource dataSource = new FileDataSource(file);
return new DataHandler(dataSource);
}
private MimeBodyPart getImgBodyPart(String resourceLocation) throws MessagingException, FileNotFoundException {
MimeBodyPart imagePort = new MimeBodyPart();
imagePort.setDataHandler(getDataHandlerByPath(resourceLocation));
imagePort.setHeader("Content-ID", "");
imagePort.setHeader("Content-Type", "image/png");
imagePort.setDisposition(MimeBodyPart.INLINE);
return imagePort;
}
/**
* 参考了
* http://www.javacui.com/java/397.html
* https://blog.csdn.net/o_o814222198/article/details/100115423
* 还是下边这个讲得清楚
* https://www.cnblogs.com/ysocean/p/7666061.html
* 使用Session.transport发送邮件到163邮箱
*/
@Override
public void sendMailByTransport(Map contentMap) {
Properties props = new Properties();
props.put("mail.smtp.host", mailFor163Config.getHost());
//需要经过授权,也就是有户名和密码的校验,这样才能通过验证(一定要有这一条)
props.put("mail.smtp.auth", true);
//设置了附件名过长问题
System.setProperty("mail.mime.splitlongparameters", "false");
//用props对象构建一个session
Session session = Session.getDefaultInstance(props);
//用session为参数定义消息对象
MimeMessage message = new MimeMessage(session);
try {
message.setFrom(mailFor163Config.getSendTo());
String[] sendTo = new String[]{mailFor163Config.getSendTo()};
InternetAddress[] Tos = new InternetAddress[sendTo.length];
for (int i = 0; i < sendTo.length; i++) {
Tos[i] = new InternetAddress(sendTo[i]);
}
message.addRecipients(Message.RecipientType.TO, Tos);
//设置在发送给收信人之前给自己(发送方)抄送一份,不然会被当成垃圾邮件,报554错
message.addRecipients(MimeMessage.RecipientType.CC, InternetAddress.parse(mailFor163Config.getSendTo()));
//加载标题----
message.setSubject(MimeUtility.encodeText(String.valueOf(contentMap.get("subject"))));
String imgPath2 = String.valueOf(contentMap.get("imgPath2"));
// 创建图片部分
MimeBodyPart imagePort = getImgBodyPart(String.valueOf(contentMap.get("imgPath1")));
MimeBodyPart imagePort2 = getImgBodyPart(imgPath2);
// TODO 这里设置的png_1、png_2分别于对应下边字符串html中的img的cid对应
imagePort.setContentID("png_1");
imagePort2.setContentID("png_2");
//设置邮件的文本内容
BodyPart htmlText = new MimeBodyPart();
htmlText.setContent(contentMap.get("htmlStr"), "text/html;charset=UTF-8");
// 将图片与文本结合在一起
MimeMultipart textAndImgPart = new MimeMultipart();
textAndImgPart.addBodyPart(htmlText);
textAndImgPart.addBodyPart(imagePort);
textAndImgPart.addBodyPart(imagePort2);
// 设置为关联关系
textAndImgPart.setSubType("related");
// 将文本与图片混合在一起
MimeBodyPart textAndImgBodyPart = new MimeBodyPart();
textAndImgBodyPart.setContent(textAndImgPart);
//创建附件内容
BodyPart attachmentBodyPart = new MimeBodyPart();
attachmentBodyPart.setDataHandler(getDataHandlerByPath(imgPath2));
// 使用MimeUtility.encodeWord编码
attachmentBodyPart.setFileName(MimeUtility.encodeWord(ResourceUtils.getFile(imgPath2).getName()));
// 设置文本+图片+附件的混合体,向multipart对象中添加邮件的各部分内容
MimeMultipart multipart = new MimeMultipart();
multipart.addBodyPart(textAndImgBodyPart);
multipart.addBodyPart(attachmentBodyPart);
// 设置为混合的
multipart.setSubType("mixed");
//将multipart对象放到message中
message.setContent(multipart);
message.setSentDate(new Date());
message.saveChanges();
Transport transport = session.getTransport("smtp");
long start = System.currentTimeMillis();
//连接服务器的邮箱,分别是host,收件人,授权码
transport.connect(mailFor163Config.getHost(), mailFor163Config.getSendTo(), mailFor163Config.getAuthCode());
//把邮件发送出去
transport.sendMessage(message, message.getAllRecipients());
log.info("Session.transport发送邮件到163邮箱: {} 毫秒", System.currentTimeMillis() - start);
transport.close();//关闭连接
} catch (MessagingException | FileNotFoundException | UnsupportedEncodingException e) {
log.error("Session.transport发送邮件到163邮箱异常", e);
}
}
/**
* 发送html以及带附件到163邮箱,建议使用该方式
* 部分参考自 https://www.cnblogs.com/moris5013/p/9729422.html
* @param contentMap 内容
*/
public void sendMailByMailSender(Map contentMap) {
javaMailSender.setHost(mailFor163Config.getHost());
// TODO 设置授权码这里不加会报错:com.sun.mail.smtp.SMTPSenderFailedException: 553 authentication is required,163 smtp1,GdxpCgAn6l7m8fRe9vGAFA--.93S2 1593111024
javaMailSender.setPassword(mailFor163Config.getAuthCode());
javaMailSender.setUsername(mailFor163Config.getSendTo());
MimeMessage mimeMessage = javaMailSender.createMimeMessage();
//设置多个收件人
String[] sendTo = new String[]{mailFor163Config.getSendTo()};
InternetAddress[] Tos = new InternetAddress[sendTo.length];
Transport transport = null;
try {
for (int i = 0; i < sendTo.length; i++) {
Tos[i] = new InternetAddress(sendTo[i]);
}
//设置在发送给收信人之前给自己(发送方)抄送一份,不然会被当成垃圾邮件,报554错
mimeMessage.addRecipients(MimeMessage.RecipientType.CC, InternetAddress.parse(mailFor163Config.getSendTo()));
mimeMessage.addRecipients(Message.RecipientType.TO, Tos);
//加载标题
mimeMessage.setSubject(MimeUtility.encodeText("我是来测试的"));
MimeMessageHelper messageHelper = new MimeMessageHelper(mimeMessage, true, "UTF-8");
messageHelper.setFrom(mailFor163Config.getSendTo());
messageHelper.setTo(mailFor163Config.getSendTo());
StringWriter writer = new StringWriter();
//实例化一个VelocityEngine对象
Properties properties = SetVelocityPro.getVelocityProperties();
VelocityEngine velocityEngine = new VelocityEngine(properties);
velocityEngine.init();
Template template = velocityEngine.getTemplate("templates/mail-vm.vm");
VelocityContext velocityContext = new VelocityContext();
velocityContext.put("test", contentMap.get("urlTest") + "-------" + contentMap.get("date"));
template.merge(velocityContext, writer);
// 用来让text内容以html格式进行展示
messageHelper.setText(writer.toString(), true);
messageHelper.addInline("identifier01", (File) contentMap.get("imgPath"));
// 添加图片附件
File pngFile = (File) contentMap.get("png");
messageHelper.addAttachment(MimeUtility.encodeWord(pngFile.getName()), new FileSystemResource(pngFile), ContentTypeEnum.PNG.getCentType());
long start = System.currentTimeMillis();
javaMailSender.send(mimeMessage);
log.info("javaMailSender发送邮件到163邮箱: {} 毫秒", System.currentTimeMillis() - start);
} catch (MessagingException | UnsupportedEncodingException e) {
log.error("使用javaMailSender发送邮件到163邮箱异常", e);
}
}
@RequestMapping("/send163")
public String sendMailTo163() {
Map contentMap = new HashMap<>();
contentMap.put("subject", "我是来测试的");
contentMap.put("imgPath1", "classpath:static/img/test.png");
contentMap.put("imgPath2", "classpath:static/img/1.png");
String html = ""
+ "这是来自一位苦逼程序猿的测试
"
+ ""
+ ""
+ "";
contentMap.put("htmlStr", html);
mailSendTo163Service.sendMailByTransport(contentMap);
return "发送163邮件成功~~~~~";
}
@RequestMapping("/sendMailTo163New")
public String sendMailTo163New() throws FileNotFoundException {
Map map = new HashMap<>();
map.put("urlTest", UUID.randomUUID());
map.put("date", DateUtils.parseDateToStr("yyyy-MM-dd HH:mm:ss", new Date()));
map.put("imgPath", ResourceUtils.getFile("classpath:static/img/test.png"));
map.put("png", ResourceUtils.getFile("classpath:static/img/1.png"));
mailSendTo163Service.sendMailByMailSender(map);
return "使用velocity发送邮件到网易成功~~~~~";
}
至于相关模板,请参见我的上一篇博客:
https://blog.csdn.net/l244112311/article/details/106954539