这篇教程演示使用腾讯企业邮箱发邮件,文中代码已在java8环境下测试通过,文中的帐户名和密码等信息请修改为自己的企业邮箱账号进行测试。
package me.zebe.cat.java.mail;
import java.util.List;
/**
* 邮件发送器
*
* @author Zebe
*/
public class MailSender implements Runnable {
/**
* 发件人别名
*/
private String fromAliasName;
/**
* 收件人
*/
private String to;
/**
* 主题
*/
private String subject;
/**
* 内容
*/
private String content;
/**
* 附件列表
*/
private List<String> attachFileList;
/**
* 构造器
* @param fromAliasName 发件人别名
* @param to 收件人
* @param subject 主题
* @param content 内容
*/
public MailSender(String fromAliasName, String to, String subject, String content) {
this.fromAliasName = fromAliasName;
this.to = to;
this.subject = subject;
this.content = content;
}
/**
* 构造器
* @param fromAliasName 发件人别名
* @param to 收件人
* @param subject 主题
* @param content 内容
* @param attachFileList 附件列表
*/
public MailSender(String fromAliasName, String to, String subject, String content, List<String> attachFileList) {
this(fromAliasName, to, subject, content);
this.attachFileList = attachFileList;
}
@Override
public void run() {
new SendEmailUtil(fromAliasName, to, subject, content, attachFileList).send();
}
}
package me.zebe.cat.java.mail;
import java.util.concurrent.*;
/**
* 邮件发送线程池
*
* @author Zebe
*/
public class MailSenderPool {
/**
* 邮件发送器线程数量
*/
private static int SENDER_TOTAL = 10;
/**
* 线程工厂(生产环境中建议使用带命名参数的线程工厂)
*/
private static ThreadFactory threadFactory = Executors.defaultThreadFactory();
/**
* 线程池执行器(采用了Spring提供的CustomizableThreadFactory,如果不需要请使用默认线程工厂)
*/
private static ExecutorService executor = new ThreadPoolExecutor(SENDER_TOTAL, 200,
0L, TimeUnit.MILLISECONDS, new LinkedBlockingQueue<>(1024), threadFactory,
new ThreadPoolExecutor.AbortPolicy());
/**
* 内部静态实例
*/
private static class Inner {
private static MailSenderPool instance = new MailSenderPool();
}
/**
* 获取实例
*
* @return 返回邮件发送线程池实例
*/
public static MailSenderPool getInstance() {
return Inner.instance;
}
/**
* 通过线程发送
*
* @param sender 邮件发送器
* @return 返回自身
*/
public MailSenderPool sendByThread(MailSender sender) {
executor.execute(sender);
return getInstance();
}
/**
* 关闭线程池
*/
public void shutDown() {
executor.shutdown();
}
}
package me.zebe.cat.java.mail;
import com.sun.mail.util.MailSSLSocketFactory;
import javax.mail.*;
import javax.mail.internet.InternetAddress;
import javax.mail.internet.MimeBodyPart;
import javax.mail.internet.MimeMessage;
import javax.mail.internet.MimeMultipart;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.security.GeneralSecurityException;
import java.util.Date;
import java.util.List;
import java.util.Properties;
/**
* 邮件发送工具类。
* 以下邮件中的配置参数,请在实际环境中,根据需要采取合适的配置方式。
* 发送邮件依赖 com.sun.mail(1.6.1) 包、javax.mail(1.5.0-b01) 包。
* 如果使用 Idea 运行,请将这两个包(可以直接到Maven目录下面去找)添加到项目的 Libraries 里面(快捷键:Ctrl + Alt + Shift + S)
*
* @author Zebe
*/
public class SendEmailUtil {
/**
* 登录用户名
*/
private final static String ACCOUNT = "[email protected]";
/**
* 登录密码
*/
private final static String PASSWORD = "xxxxxxx";
/**
* 邮件服务器地址
*/
private final static String HOST = "smtp.exmail.qq.com";
/**
* 发信端口
*/
private final static String PORT = "465";
/**
* 发信协议
*/
private final static String PROTOCOL = "ssl";
/**
* 发件人别名(可以为空)
*/
private String fromAliasName;
/**
* 收件人
*/
private String to;
/**
* 主题
*/
private String subject;
/**
* 内容
*/
private String content;
/**
* 附件列表(可以为空)
*/
private List<String> attachFileList;
/**
* 构造器
*
* @param fromAliasName 发件人别名
* @param to 收件人
* @param subject 主题
* @param content 内容
* @param attachFileList 附件列表
*/
public SendEmailUtil(String fromAliasName, String to, String subject, String content, List<String> attachFileList) {
this.fromAliasName = fromAliasName;
this.to = to;
this.subject = subject;
this.content = content;
this.attachFileList = attachFileList;
}
/**
* 认证信息
*/
static class MyAuthenticator extends Authenticator {
/**
* 用户名
*/
String username = null;
/**
* 密码
*/
String password = null;
/**
* 构造器
*
* @param username 用户名
* @param password 密码
*/
public MyAuthenticator(String username, String password) {
this.username = username;
this.password = password;
}
@Override
protected PasswordAuthentication getPasswordAuthentication() {
return new PasswordAuthentication(username, password);
}
}
/**
* 发送邮件
*/
public void send() {
// 设置邮件属性
Properties prop = new Properties();
prop.setProperty("mail.transport.protocol", PROTOCOL);
prop.setProperty("mail.smtp.host", HOST);
prop.setProperty("mail.smtp.port", PORT);
prop.setProperty("mail.smtp.auth", "true");
MailSSLSocketFactory sslSocketFactory = null;
try {
sslSocketFactory = new MailSSLSocketFactory();
sslSocketFactory.setTrustAllHosts(true);
} catch (GeneralSecurityException e1) {
e1.printStackTrace();
}
if (sslSocketFactory == null) {
System.err.println("开启 MailSSLSocketFactory 失败");
} else {
prop.put("mail.smtp.ssl.enable", "true");
prop.put("mail.smtp.ssl.socketFactory", sslSocketFactory);
// 创建邮件会话(注意,如果要在一个进程中切换多个邮箱账号发信,应该用 Session.getInstance)
Session session = Session.getDefaultInstance(prop, new MyAuthenticator(ACCOUNT, PASSWORD));
// 开启调试模式(生产环境中请不要开启此项)
session.setDebug(true);
try {
MimeMessage mimeMessage = new MimeMessage(session);
// 设置发件人别名(如果未设置别名就默认为发件人邮箱)
if (fromAliasName != null && !fromAliasName.trim().isEmpty()) {
mimeMessage.setFrom(new InternetAddress(ACCOUNT, fromAliasName));
}
// 设置主题和收件人、发信时间等信息
mimeMessage.addRecipient(Message.RecipientType.TO, new InternetAddress(to));
mimeMessage.setSubject(subject);
mimeMessage.setSentDate(new Date());
// 如果有附件信息,则添加附件
if (!attachFileList.isEmpty()) {
Multipart multipart = new MimeMultipart();
MimeBodyPart body = new MimeBodyPart();
body.setContent(content, "text/html; charset=UTF-8");
multipart.addBodyPart(body);
// 添加所有附件(添加时判断文件是否存在)
for (String filePath : attachFileList) {
if (Files.exists(Paths.get(filePath))) {
MimeBodyPart tempBodyPart = new MimeBodyPart();
tempBodyPart.attachFile(filePath);
multipart.addBodyPart(tempBodyPart);
}
}
mimeMessage.setContent(multipart);
} else {
mimeMessage.setText(content);
}
// 开始发信
mimeMessage.saveChanges();
Transport.send(mimeMessage);
} catch (MessagingException e) {
e.printStackTrace();
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
package me.zebe.cat.java.mail;
import java.util.Arrays;
import java.util.List;
/**
* 发送邮件测试
*
* @author Zebe
*/
public class SendMailTest {
/**
* 运行入口
*
* @param args 运行参数
*/
public static void main(String[] args) {
// 设置发信参数
final String fromAliasName = "自定义别名Test";
final String to = "[email protected]";
final String subject = "腾讯企业邮箱发信测试";
final String content = "带多个附件的邮件测试
这是邮件内容正文。
";
// 设置附件路径(注意:res 是项目根目录下的一个文件夹)
final List<String> attachFileList = Arrays.asList("res/1.png", "res/1.pdf");
// 通过线程池发送邮件
MailSenderPool pool = MailSenderPool.getInstance();
pool.sendByThread(new MailSender(fromAliasName, to, subject, content, attachFileList)).shutDown();
}
}
本文演示的是纯Java项目进行腾讯企业邮箱发信的例子,文中的帐户名和密码等信息请修改为自己的企业邮箱账号进行测试。
本文首发于个人独立博客,文章链接:http://www.zebe.me/java-send-tencent-exmail