邮件发送器
/**
* 邮件发送器
*
* @author Zebe
*/
public class MailSender implements Runnable {
/**
* 收件人
*/
private String to;
/**
* 收件人名称
*/
private String toName;
/**
* 主题
*/
private String subject;
/**
* 内容
*/
private String content;
/**
* 附件列表
*/
private List<String> attachFileList;
/**
* 构造器
* @param to 收件人
* @param subject 主题
* @param content 内容
*/
public MailSender(String to,String toName, String subject, String content) {
this.to = to;
this.toName = toName;
this.subject = subject;
this.content = content;
}
/**
* 构造器
* @param to 收件人
* @param subject 主题
* @param content 内容
* @param attachFileList 附件列表
*/
public MailSender(String to, String toName,String subject, String content, List<String> attachFileList) {
this(to, toName, subject, content);
this.attachFileList = attachFileList;
}
@Override
public void run() {
new SendEmailUtil(to,toName, subject, content, attachFileList).send();
}
}
邮件发送线程池
/**
* 邮件发送线程池
*
* @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();
}
}
邮件发送工具类
/**
* 邮件发送工具类。
* 以下邮件中的配置参数,请在实际环境中,根据需要采取合适的配置方式。
* 发送邮件依赖 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 fromAliasName = "****";
/**
* 登录用户名
*/
private String ACCOUNT;
/**
* 登录密码
*/
private String PASSWORD;
/**
* 邮件服务器地址
*/
//QQ企业邮箱:smtp.exmail.qq.com
//网易企业邮箱:smtphz.qiye.163.com
private String HOST;
/**
* 发信端口
*/
//QQ企业邮箱:465
//网易企业邮箱:994
private String PORT;
/**
* 发信协议
*/
private final static String PROTOCOL = "ssl";
/**
* 收件人
*/
private String to;
/**
* 收件人名称
*/
private String toName;
/**
* 主题
*/
private String subject;
/**
* 内容
*/
private String content;
/**
* 附件列表(可以为空)
*/
private List<String> attachFileList;
/**
* 构造器
*
* @param attachFileList 附件列表
*/
public SendEmailUtil(MailTemplate mailTemplate, List<String> attachFileList) {
this.to = mailTemplate.getTo();
this.toName = mailTemplate.getToName();
this.subject = mailTemplate.getSubject();
this.content = mailTemplate.getContent();
this.attachFileList = attachFileList;
this.ACCOUNT = mailTemplate.getAccount();
this.PASSWORD = mailTemplate.getPassword();
switch (mailTemplate.getSendType()) {
case "qq":
this.HOST = "smtp.exmail.qq.com";
this.PORT = "465";
break;
case "163":
this.HOST = "smtp.ym.163.com";
this.PORT = "994";
break;
}
}
/**
* 认证信息
*/
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 boolean 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);
// 设置发件人别名(如果未设置别名就默认为发件人邮箱)
mimeMessage.setFrom(new InternetAddress(ACCOUNT, fromAliasName));
// 设置主题和收件人、发信时间等信息
mimeMessage.addRecipient(Message.RecipientType.TO, new InternetAddress(to, toName));
mimeMessage.setSubject(subject);
mimeMessage.setSentDate(new Date());
//图片
MimeBodyPart img = new MimeBodyPart();
DataHandler dh = new DataHandler(new FileDataSource("src/main/resources/2.jpg"));//图片路径
img.setDataHandler(dh);
img.setContentID("img");
//正文
MimeBodyPart text = new MimeBodyPart();
text.setContent("这里正文内容 for img<img src='cid:img'><br/>", "text/html;charset=utf-8"); //注意编码问题
//描述数据关系
MimeMultipart mm = new MimeMultipart();
mm.addBodyPart(text);
mm.addBodyPart(img);
mm.setSubType("related");
//图片-文本--复合--转普通节点
MimeBodyPart tex_image_tPart=new MimeBodyPart();
tex_image_tPart.setContent(mm);
// 如果有附件信息,则添加附件
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 {
// Multipart multipart = new MimeMultipart();
// MimeBodyPart body = new MimeBodyPart();
// body.setContent(mm, "text/html; charset=UTF-8");
// multipart.addBodyPart(body);
MimeMultipart mimeMultipart1=new MimeMultipart();
mimeMultipart1.addBodyPart(tex_image_tPart);
mimeMultipart1.setSubType("mixd");//混合关系
mimeMessage.setContent(mimeMultipart1, "text/html; charset=UTF-8");
//mimeMessage.setText(content);
}
// 开始发信
mimeMessage.saveChanges();
Transport.send(mimeMessage);
return true;
} catch (MessagingException | IOException e) {
e.printStackTrace();
return false;
}
}
return false;
}
}
示例
public static void main(String[] args) {
try {
int num;
// 通过线程池发送邮件
MailSenderPool pool = MailSenderPool.getInstance();
for (num=1;num<=73;num++){
// 设置发信参数
final String toName = "我是" + num + "号";
final String to = "test" + num + "@***.com";
String subject = num + " 第一次发送测试邮件标题";
final String content = "<p style='color:red'>这是邮件内容正文。</p>";
// 设置附件路径(注意:res 是项目根目录下的一个文件夹)
// final List<String> attachFileList = Arrays.asList("res/1.png", "res/1.pdf");
pool.sendByThread(new MailSender(to,toName, subject, content, new ArrayList<>()));
subject = num + " 第二次发送测试邮件标题";
pool.sendByThread(new MailSender(to,toName, subject, content, new ArrayList<>()));
}
pool.shutDown();
}catch (Exception e){
System.out.println("错误: " + e);
}
}