导入依赖/jar包
通过maven导入javax.mail和javax.activation的依赖,或者去Maven Repository 下载这两个包(注意包名),这两个包已经完善了,不会再有新版本,可以直接复制粘贴。
<dependency>
<groupId>javax.mail</groupId>
<artifactId>mail</artifactId>
<version>1.4.7</version>
</dependency>
<dependency>
<groupId>javax.activation</groupId>
<artifactId>activation</artifactId>
<version>1.1.1</version>
</dependency>
申请邮件服务器方的POP3/SMTP授权码
这里以QQ邮箱为例,其他的也差不多。
设置->账户->往下拉->开启POP3/SMTP服务。
发送一封简单邮件
发送一封不带附件的邮件
发件人是固定的,不需要传参哦,如果改变发件人,就要改授权码对应改发件人的授权码
/**
* 发送仅包含html文本的邮件
*
* @param to 收件人
* @param subject 邮件主题
* @param msg 邮件内容
* @param log 是否开启日志
*/
public static void sendMessage(String to, String subject, String msg, boolean log){
try {
Properties properties = new Properties();
// 设置QQ邮件服务器,发件人邮箱地址必须是该邮箱服务器的邮箱
properties.setProperty("mail.host","smtp.qq.com");
properties.setProperty("mail.transport.protocol","smtp"); // 指定发送协议为smtp
properties.setProperty("mail.smtp.auth","true"); // 需要验证用户名密码
// 邮件加密
MailSSLSocketFactory factory = new MailSSLSocketFactory();
factory.setTrustAllHosts(true);
properties.put("mail.smtp.ssl.enable","true");
properties.put("mail.smtp.ssl.socketFactory",factory);
Session session = Session.getDefaultInstance(properties, new Authenticator() {
@Override
protected PasswordAuthentication getPasswordAuthentication() {
return new PasswordAuthentication("发件人邮箱xxxxxxx@xx.xxx","授权码");
}
});
// 开启Session的debug模式,可以看到发送时的日志输出,不设置此属性默认为false,不输出日志
session.setDebug(log);
// 通过session获得transport对象,用于发送邮件
Transport transport = session.getTransport();
transport.connect("smtp.qq.com","发件人邮箱xxxxxxx@xx.xxx","授权码");
// 创建邮件对象
MimeMessage mimeMessage = new MimeMessage(session);
// 指定发件人
mimeMessage.setFrom(new InternetAddress("发件人邮箱xxxxxxx@xx.xxx"));
// 指定收件人
mimeMessage.setRecipient(Message.RecipientType.TO,new InternetAddress(to));
// 设置邮件主题
mimeMessage.setSubject(subject);
// 设置邮件正文文本
mimeMessage.setContent(msg,"text/html;charset=utf-8");
// 发送邮件
transport.sendMessage(mimeMessage,mimeMessage.getAllRecipients());
// 关闭连接
transport.close();
} catch (GeneralSecurityException | MessagingException e) {
System.out.println("邮件发送失败");
e.printStackTrace();
}
}
*发送一封完整的邮件
发送一封完整的邮件,包含主题,正文文本,图片附件,文件附件。
约定:文件路径/图片路径数组各元素必须和其文件名/别名数组一一对应。
也可通过该方法发送简单邮件,把不需要的东西入参时传入null
这个方法我已经封装的尽可能完善了,可以直接拿去用
/**
* 发送一封完整的邮件,包含主题,正文文本,图片附件,文件附件
* @param to 收件人邮箱地址 不能为空
* @param subject 邮件主题 不能为空
* @param msg 正文文本html 不能为空
* @param imgPaths 图片本地路径 可以为空 为空则imgAlias也要为空(imgAlias不为空没有意义)
* @param imgAlias 图片别名,指定别名后可在正文html中通过cid引用该图片 可以为空
* @param filePaths 文件本地路径 可以为空 为空则fileAlias也要为空(fileNames不为空没有意义)
* @param fileNames 文件名 可以为空 文件名是收件方下载时的文件名,需要带文件后缀
* @param log 是否开启日志输出
*/
public static void sendMessage(@NotNull String to,@NotNull String subject, @NotNull String msg,
String[] imgPaths, String[] imgAlias,
String[] filePaths,String[] fileNames,boolean log){
try {
Properties properties = new Properties();
properties.setProperty("mail.host","smtp.qq.com");
properties.setProperty("mail.transport.protocol","smtp");
properties.setProperty("mail.smtp.auth","true");
MailSSLSocketFactory factory = new MailSSLSocketFactory();
factory.setTrustAllHosts(true);
properties.put("mail.smtp.ssl.enable","true");
properties.put("mail.smtp.ssl.socketFactory",factory);
Session session = Session.getDefaultInstance(properties, new Authenticator() {
@Override
protected PasswordAuthentication getPasswordAuthentication() {
return new PasswordAuthentication("发件人邮箱xxxxxxx@xx.xxx","授权码");
}
});
session.setDebug(log);
Transport transport = session.getTransport();
transport.connect("smtp.qq.com","发件人邮箱xxxxxxx@xx.xxx","授权码");
MimeMessage mimeMessage = new MimeMessage(session);
mimeMessage.setFrom(new InternetAddress("发件人邮箱xxxxxxx@xx.xxx"));
mimeMessage.setRecipient(Message.RecipientType.TO,new InternetAddress(to));
mimeMessage.setSubject(subject);
MimeMultipart contentParts = new MimeMultipart(); // 正文中的模块
// 判断入参
if (imgPaths != null && imgAlias != null && imgPaths.length == imgAlias.length){
// 向正文中添加图片附件
for (int i = 0; i < imgPaths.length; i++) {
MimeBodyPart img = new MimeBodyPart();
DataHandler handler = new DataHandler(new FileDataSource(imgPaths[i]));
img.setDataHandler(handler);
img.setContentID(imgAlias[i]); // 设置图片别名
contentParts.addBodyPart(img);
}
}
// 邮件正文文本
MimeBodyPart contentText = new MimeBodyPart();
contentText.setContent(msg,"text/html;charset=utf-8");
// 向正文模块中添加正文文本
contentParts.addBodyPart(contentText);
contentParts.setSubType("related");
// 把正文模块设置到正文中
MimeBodyPart content = new MimeBodyPart(); // 正文
content.setContent(contentParts);
MimeMultipart email = new MimeMultipart(); // 相当于整封邮件
// 判断入参
if (filePaths != null && fileNames != null && filePaths.length == fileNames.length){
// 向邮件中添加文件附件
for (int i = 0; i < filePaths.length; i++) {
MimeBodyPart file = new MimeBodyPart();
DataHandler handler = new DataHandler(new FileDataSource(filePaths[i]));
file.setDataHandler(handler);
file.setFileName(fileNames[i]); // 设置文件名
email.addBodyPart(file);
}
}
email.addBodyPart(content);
email.setSubType("mixed");
mimeMessage.setContent(email);
mimeMessage.saveChanges();
transport.sendMessage(mimeMessage,mimeMessage.getAllRecipients());
transport.close();
} catch (GeneralSecurityException | MessagingException e) {
System.out.println("邮件发送失败");
e.printStackTrace();
}
}
Test
注意content中标签的src属性是"cid:first",就是上面给的图片别名,通过图片别名来引用该图片,因此需要一一对应
String[] imgPaths = {"src/1.jpg","src/2.jpg"};
String[] imgAlias = {"first","second"};
String[] filePaths = {"src/my.xml","src/db.properties"};
String[] fileAlias = {"my.xml","db.properties"};
//正文文本html
String content = "<img src='cid:first' style='width:100px;height:100px'/>" +
"张三<h2 style='color:yellow;display:inline'>李四</h2>和王五" +
"<img src='cid:second' style='width:100px;height:100px'/>";
// 全参数的完整邮件
sendMessage("收件人邮箱地址","完整邮件测试",content,imgPaths,imgAlias,filePaths,fileAlias,true);
// 不带文件附件的邮件
sendMessage("收件人邮箱地址","完整邮件测试",content,imgPaths,imgAlias,null,null,true);
// 不带图片附件的邮件
sendMessage("收件人邮箱地址","完整邮件测试",content,null,null,filePaths,fileAlias,true);
// 仅正文的简单邮件
sendMessage("收件人邮箱地址","完整邮件测试",content,null,null,null,null,true);
...
// 我不知道可不可以发没有正文的邮件,但是我寻思应该没人会发正文都没有的邮件吧。。。
结果
测试时也可以自己给自己发,但是不建议发太多内容重复的邮件,容易被检测成垃圾邮件,如果发送成功找不到邮件,可以去垃圾箱看看。