1. 简介
Java的发送邮件的组合一直让人比较困惑,这里做一个简单的小结和说明一些注意事项。
MimeBodyPart可以是文本、HTML、图片附件,也可以是MimeMultiPart。
MimeMultiPart是多个MimeBodyPart的组合,这样就可以通过嵌套的方式完成复杂邮件的组合。
2. sender与from
mimeMessage.setFrom(fromAddress);
mimeMessage.setSender(senderAddress);
from:表示邮件是谁想发的,必须和下面的transport连接的时候使用的user一致:
transport.connect(host, user, pass);
sender:sender表示发件人,邮件中可以看到发件人可以看到sender代表from发送,使用的用户名和密码还是from的。
如果想要让邮件显眼,一看就知道是谁发的,可以使用:
title<邮箱地址>
例如:
InternetAddress fromAddress = new InternetAddress(String.format("%s<%s>",MimeUtility.encodeText("技术部"),from));
MimeUtility.encodeText可以处理中文问题。
3. RecipientType
- Message.RecipientType.TO :接收
- Message.RecipientType.CC :抄送
- Message.RecipientType.BCC:密送
4. Multipart subtype
mimeMultipart.setSubType("related");
- mixed:混合关系,一般正文和附件组合使用mixed,如果不设置,javamail默认会使用mixed
- related:关联关系,一般html引用了图片这类内嵌资源,正文和图片组合使用related
- alternative:同时存在纯文本与超文本,使用boundary分割
邮件可能会分段,使用的是boundary中定义的字符串作为标识。
- 段体内的每个子段以:【--加boundary】行开始
- 父段则以:【--加boundary加--】行结束
- 不同段之间用空行分隔
大概像下面这样的:
Content-Type: multipart/mixed;
boundary="----=_Part_1_293907205.1610941392421"
------=_Part_1_293907205.1610941392421
Content-Type: multipart/related;
boundary="----=_Part_0_1259652483.1610941392409"
------=_Part_0_1259652483.1610941392409
Content-Type: application/octet-stream
Content-Transfer-Encoding: base64
Content-ID: haha
可以使用:
mimeMessage.writeTo(new FileOutputStream("G:\\picture\\tmp.eml"));
将邮件保存到本地,然后使用文本编辑器打开查看。
5. Store与Folder
5.1 Store
Store表示存储邮件的服务器,接收邮件
// 存储邮件的服务器,采用pop3协议
Store store = session.getStore("pop3");
// 连接邮件服务器
store.connect(host,username,passworsd);
5.2 Folder
Folder表示收件箱目录对象
Folder folder = store.getFolder("tmp");
// 以只读的方式打开目录
folder.open(Folder.READ_ONLY);
// 获取目录下的邮件信息
Message message[ ] = folder.getMessages();
6. 示例
public enum MailConfig {
M163("mail.163.com","xxx@163.com","xxx");
private String server;
private String user;
private String pass;
MailConfig(String server, String user, String pass) {
this.server = server;
this.user = user;
this.pass = pass;
}
public String getUser() {
return user;
}
public void setUser(String user) {
this.user = user;
}
public String getPass() {
return pass;
}
public void setPass(String pass) {
this.pass = pass;
}
public String getServer() {
return server;
}
public void setServer(String server) {
this.server = server;
}
}
import javax.mail.MessagingException;
import javax.mail.Session;
import javax.mail.Transport;
import javax.mail.internet.MimeMessage;
import java.util.Properties;
public class MailSenderHelper {
public static Session getSession(MailConfig config){
Properties properties = new Properties();
properties.setProperty("mail.host", config.getServer());
properties.setProperty("mail.transport.protocol", "smtp");
properties.setProperty("mail.smtp.auth", "true");
Session session = Session.getInstance(properties);
session.setDebug(false);
return session;
}
public static Transport getTransport(MailConfig config) throws MessagingException {
Session session = getSession(config);
Transport transport = session.getTransport();
transport.connect(config.getServer(), config.getUser(), config.getPass());
return transport;
}
public static void send(MailConfig config, MimeMessage mimeMessage) throws MessagingException {
Transport transport = getTransport(config);
transport.sendMessage(mimeMessage, mimeMessage.getAllRecipients());
transport.close();
}
}
import javax.activation.DataHandler;
import javax.activation.FileDataSource;
import javax.mail.Session;
import javax.mail.internet.InternetAddress;
import javax.mail.internet.MimeBodyPart;
import javax.mail.internet.MimeMessage;
import javax.mail.internet.MimeMultipart;
import javax.mail.internet.MimeUtility;
import java.util.Date;
import java.util.List;
public class HtmlEmailHelper {
private static final String TEXT_HTML_CHARSET_UTF_8 = "text/html;charset=UTF-8";
private static final String UTF8 = "UTF-8";
public static void sendHtmlEmail(
MailConfig config,
String from,
String nickname,
List<String> tos,
String subject,
String html,
List<String> imgs,
List<String> attachs
) throws Exception{
Session session = MailSenderHelper.getSession(config);
MimeMessage mimeMessage = new MimeMessage(session);
// InternetAddress senderAddress = new InternetAddress(config.getUser());
// InternetAddress fromAddress = new InternetAddress(from);
InternetAddress fromAddress = new InternetAddress(String.format("%s<%s>",MimeUtility.encodeText("技术部"),config.getUser()));
InternetAddress senderAddress = new InternetAddress(String.format("%s<%s>",MimeUtility.encodeText(nickname),from));
// if(StringUtils.isNotBlank(nickname)){
// mimeMessage.setFrom(new InternetAddress(String.format("%s<%s>",nickname,from)));
// }else {
// mimeMessage.setFrom(fromAddress);
// }
mimeMessage.setFrom(fromAddress);
mimeMessage.setSender(senderAddress);
for (String to : tos) {
mimeMessage.addRecipient(MimeMessage.RecipientType.TO, new InternetAddress(to));
}
mimeMessage.setSubject(subject,UTF8);
DataHandler dh;
FileDataSource fileDataSource;
MimeMultipart mimeMultipart = new MimeMultipart();//html 与 图片
// 添加图片部分
if(imgs != null && imgs.size() > 0) {
for (String img : imgs) {
MimeBodyPart image = new MimeBodyPart();
fileDataSource = new FileDataSource(img);
dh = new DataHandler(fileDataSource);
image.setDataHandler(dh);
String name = dh.getName();
int dotIndex = name.lastIndexOf(".");
if(dotIndex != -1){
name = name.substring(0,dotIndex);
}
String contentID = MimeUtility.encodeText(name);
image.setContentID(contentID);//<img src='cid:contentID'/>
mimeMultipart.addBodyPart(image);
}
}
// 添加HTML节点
MimeBodyPart text = new MimeBodyPart();
text.setContent(html, TEXT_HTML_CHARSET_UTF_8);
// 将HTML和图片合成一个MimeMultiPart
mimeMultipart.addBodyPart(text);
// 因为html可能引用图片,所以关系设置为related,这样图片就不会显示在附件中
mimeMultipart.setSubType("related");
// 新建一个MimeMultipart存放最终内容:HTML图片部分 + 附件
MimeMultipart mailMimeMultipart = new MimeMultipart();
// 将HTML与图片的MimeMultiPart混合部分封装成一个MimeBodyPart
MimeBodyPart txtImgMimeBodyPart = new MimeBodyPart();
txtImgMimeBodyPart.setContent(mimeMultipart);
// 添加HTML图片部分
mailMimeMultipart.addBodyPart(txtImgMimeBodyPart);
// 添加附件部分
MimeBodyPart attachment;
if(attachs != null && attachs.size() > 0) {
for (String attach : attachs) {
attachment = new MimeBodyPart();
fileDataSource = new FileDataSource(attach);
dh = new DataHandler(fileDataSource);
attachment.setDataHandler(dh);
attachment.setFileName(MimeUtility.encodeText(dh.getName()));
mailMimeMultipart.addBodyPart(attachment);
}
}
// HTML图片部分一般和附件没啥直接关系,所以关联关系设置为mixed
// mailMimeMultipart.setSubType("mixed");
mailMimeMultipart.setSubType("alternative");
// 将MimeMessage的内容设置为组合好的最后的MimeMultipart部分
mimeMessage.setContent(mailMimeMultipart);
//设置邮件的发送时间,默认立即发送
mimeMessage.setSentDate(new Date());
// mimeMessage.saveChanges();
//将邮件写入指定的路径
// mimeMessage.writeTo(new FileOutputStream("G:\\picture\\tmp.eml"));
MailSenderHelper.send(config,mimeMessage);
}
}