复杂邮件的发送,主要是创建邮件时,内容的设置不同:
代码实现:
package top.jacktu.test;
import java.io.UnsupportedEncodingException;
import java.util.Date;
import java.util.Properties;
import javax.activation.DataHandler;
import javax.activation.FileDataSource;
import javax.mail.Message.RecipientType;
import javax.mail.MessagingException;
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 javax.mail.internet.MimeUtility;
public class MailUtil {
// 发件人的 邮箱 和 密码(替换为自己的邮箱和密码)
private static String myEmailAccount = "xxxxx@163.com";
private static String myEmailPassword = "xxxxx";
// 发件人邮箱的 SMTP 服务器地址, 必须准确, 不同邮件服务器地址不同, 一般格式为: smtp.xxx.com
// 网易163邮箱的 SMTP 服务器地址为: smtp.163.com
private static String myEmailSMTPHost = "smtp.163.com";
// 收件人邮箱(替换为自己知道的有效邮箱)
private static String receiveMailAccount = "123456@qq.com";
private static String senderNickName = "发件人昵称";
private static String recipientsNickName = "收件人昵称";
private static String mailSubject = "邮件主题";
// private static String mailContent = "邮件内容";
public static void main(String[] args) throws Exception {
// 1. 创建参数配置, 用于连接邮件服务器的参数配置
Properties config = new Properties();
config.setProperty("mail.transport.protocol", "smtp"); // 使用的协议(JavaMail规范要求)
config.setProperty("mail.smtp.host", myEmailSMTPHost); // 发件人的邮箱的 SMTP 服务器地址
config.setProperty("mail.smtp.auth", "true"); // 需要请求认证
// 2. 根据配置创建会话对象, 用于和邮件服务器交互
Session session = Session.getInstance(config);
// 设置为debug模式, 可以查看详细的发送 log
session.setDebug(true);
// 3. 创建一封邮件
MimeMessage mail = createMimeMessage(session);
// 也可以保持到本地查看
// message.writeTo(file_out_put_stream);
// 4. 根据 Session 获取邮件传输对象
Transport transport = session.getTransport();
// 5. 使用 邮箱账号 和 密码 连接邮件服务器
// 这里认证的邮箱必须与 message 中的发件人邮箱一致,否则报错
transport.connect(myEmailAccount, myEmailPassword);
// 6. 发送邮件, 发到所有的收件地址, message.getAllRecipients() 获取到的是在创建邮件对象时添加的所有收件人, 抄送人, 密送人
transport.sendMessage(mail, mail.getAllRecipients());
// 7. 关闭连接
transport.close();
}
/**
* 创建邮件
* */
public static MimeMessage createMimeMessage (Session session) throws Exception {
// 1. 创建邮件对象
MimeMessage mail = new MimeMessage(session);
// 2. From: 发件人
mail.setFrom(new InternetAddress(myEmailAccount, senderNickName, "UTF-8"));
// 3. To: 收件人(可以增加多个收件人、抄送、密送)
mail.addRecipient(RecipientType.TO, new InternetAddress(receiveMailAccount, recipientsNickName, "UTF-8"));
/**
* 添加抄送人,抄送给自己
* 不加有可能报一个异常:
* 554 DT:SPM
* DT:SPM 发送的邮件内容包含了未被许可的信息,或被系统识别为垃圾邮件。请检查是否有用户发送病毒或者垃圾邮件;
* (包含Test 等垃圾信息,会报 DT:SPM)
*/
mail.addRecipients(MimeMessage.RecipientType.CC, InternetAddress.parse(myEmailAccount));
// 4. Subject: 邮件主题
mail.setSubject(mailSubject);
/**
* 一般 JavaMail 只需要使用这个功能就足够了 </br>
* 用这个内容设置 一个超链接,完成注册 或者 找回密码就行了
* (设置内容,前面设置的内容会被覆盖!)
*/
// mail.setText(mailContent);
// 创建并添加复杂的 内容
createAndMimeMultipart(mail);
// 12. 设置发件时间
mail.setSentDate(new Date());
// 13. 保存上面的所有设置
mail.saveChanges();
return mail;
}
/**
* 为邮件创建一些其他内容 </br>
* 并添加入 邮件
* @param mail
* @throws MessagingException
* @throws UnsupportedEncodingException
* */
private static MimeMultipart createAndMimeMultipart(MimeMessage mail)
throws MessagingException, UnsupportedEncodingException {
// 1.创建 图片节点
MimeBodyPart image = new MimeBodyPart();
// 2.创建数据处理器 (项目目录下 要有对应的文件)
DataHandler imageDH = new DataHandler(new FileDataSource("周冬雨1.jpg"));
// 3.把数据处理器添加入,图片节点
image.setDataHandler(imageDH);
// 4.设置 cid 作 图片引用作用
image.setContentID("image_cid");
// 5.创建文本节点
MimeBodyPart text = new MimeBodyPart();
// 6.设置内容和 内容类型 text.setContent(obect, type);
// 这里设置是 html 类型,html标签都会被解析出来
text.setContent("<h1>啥都没有么</h1><img src='cid:image_cid' />"
+ "<p>我滴图片呢</p>","text/html;charset=utf-8");
//添加一些其他附件,我这里是 txt 格式的 ,实际上你添加 如: doc 任何格式都行
MimeBodyPart attachment = new MimeBodyPart();
DataHandler attaDH = new DataHandler(new FileDataSource("自增.txt"));
attachment.setDataHandler(attaDH);
attachment.setFileName(MimeUtility.encodeText(attaDH.getName()));
MimeBodyPart ai = new MimeBodyPart();
DataHandler aiDH = new DataHandler(new FileDataSource("王丽坤.jpg"));
ai.setDataHandler(aiDH);
ai.setFileName(MimeUtility.encodeText(aiDH.getName()));
MimeBodyPart txtCon = new MimeBodyPart();
txtCon.setContent("<span style='color:red'>红色的字体</span>"
+ "<p>p标签</p>", "text/html;charset=utf-8");
/**
* 上面的 图片+文本 节点 可以这样操作,封装在一起.
* 但是 操作,繁琐不建议.
*/
// (文本+图片)设置 文本 和 图片 “节点”的关系(将 文本 和 图片 “节点”合成一个混合“节点”)
// MimeMultipart mm_text_image = new MimeMultipart();
// mm_text_image.addBodyPart(text);
// mm_text_image.addBodyPart(image);
// mm_text_image.setSubType("related"); // 关联关系
// 将 文本+图片 的混合“节点”封装成一个普通“节点”
// 最终添加到邮件的 Content 是由多个 BodyPart 组成的 Multipart, 所以我们需要的是 BodyPart,
// 上面的 mm_text_image 并非 BodyPart, 所有要把 mm_text_image 封装成一个 BodyPart
// MimeBodyPart text_image = new MimeBodyPart();
// text_image.setContent(mm_text_image);
MimeMultipart mimeMultipart = new MimeMultipart();
// 只要同时包含 了 图片节点(含 cid),和 对应 的引用 就能显示出来 图片
mimeMultipart.addBodyPart(text);
mimeMultipart.addBodyPart(image);
mimeMultipart.addBodyPart(attachment);
mimeMultipart.addBodyPart(ai);
mimeMultipart.addBodyPart(txtCon);
// 上面几个 addBodyPart 邮件显示顺序可能和这里设置的不一样.
// 用 重载的方法 addBodyPart(MimeBodyPart,index) 就可以解决
// 把混合节点设置为 邮件 内容
mail.setContent(mimeMultipart);
return mimeMultipart;
}
}
电脑网页登陆QQ邮箱效果 (图片被拦截):
图被拦截显示,可以明显看到 图片被有一行: 这不是腾讯公司的... 图片未被显示. 可以点选显示图片
手机登陆QQ邮箱效果:
(这是一封邮件,一屏幕截图不下)
效果看起来 除了电脑不能显示图片(qq邮箱拦截的) 其他都差不多