人工智能
308
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的。
如果想要让邮件显眼,一看就知道是谁发的,可以使用:
例如:
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); } }