Java 发送匿名邮件、普通邮件
2020-04-21 10:06:53
通过 javax.mail 实现一个发送邮件的工具类(支持发送匿名邮件、附件邮件)
可用于发送简单的预警日志等场景
工具类 MailSender.java:
```
package com.fiebug.common.util;
import javax.activation.DataHandler;
import javax.activation.DataSource;
import javax.mail.Message;
import javax.mail.MessagingException;
import javax.mail.Session;
import javax.mail.Transport;
import javax.mail.internet.*;
import javax.naming.Context;
import javax.naming.NamingEnumeration;
import javax.naming.NamingException;
import javax.naming.directory.Attribute;
import javax.naming.directory.Attributes;
import javax.naming.directory.DirContext;
import javax.naming.directory.InitialDirContext;
import javax.net.ssl.SSLSocketFactory;
import java.io.UnsupportedEncodingException;
import java.util.Date;
import java.util.Hashtable;
import java.util.Properties;
/**
* 邮件发送者
*
* @author Null / test@fiebug.com
*/
public class MailSender {
private String host;
private String port;
private String user;
private String password;
private boolean isAnonymous = false;
private boolean debug = false;
private static final String CHARACTER_ENCODING = "UTF-8";
private static final String MAIL_TYPE = "text/html;charset=UTF-8";
private static final String ANONYMOUS_EMAIL = "anonymous@anonymous.com";
private MailSender() {
this.isAnonymous = true;
}
private MailSender(String host, String port, String user, String password) {
this.host = host;
this.port = port;
this.user = user;
this.password = password;
}
/**
* 获取匿名 MailSender 实例
*
* @return
*/
public static MailSender getInstance() {
return new MailSender();
}
/**
* 获取 MailSender 实例
*
* @param host
* @param port
* @param user
* @param password
* @return
*/
public static MailSender getInstance(String host, String port, String user, String password) {
return new MailSender(host, port, user, password);
}
/**
* 发送邮件
*
* @param from 发送者邮箱
* @param to 接收者邮箱
* @param subject 主题
* @param content 正文
* @param attachments DataSource 接口常用的实现有 FileDataSource ByteArrayDataSource
* @return
*/
public void sendMessage(String from, String to, String subject, String content, DataSource... attachments) {
try {
if (from == null || from.isEmpty()) {
from = ANONYMOUS_EMAIL;
}
MimeMultipart mimeMultipart = new MimeMultipart();
// 添加正文
MimeBodyPart contentMimeBody = new MimeBodyPart();
contentMimeBody.setContent(content, MAIL_TYPE);
mimeMultipart.addBodyPart(contentMimeBody);
// 添加附件
MimeBodyPart bodyPart;
String nameEncoded;
for (DataSource attachment : attachments) {
bodyPart = new MimeBodyPart();
bodyPart.setDataHandler(new DataHandler(attachment));
nameEncoded = encodeText(attachment.getName());
// 普通附件文件名
bodyPart.setFileName(nameEncoded);
String contentType = attachment.getContentType();
if (contentType != null && contentType.toLowerCase().startsWith("image/")) {
// 图片附件,用于正文中引用图片
bodyPart.setContentID(nameEncoded);
}
mimeMultipart.addBodyPart(bodyPart);
}
sendMessage(from, to, subject, mimeMultipart);
} catch (Exception e) {
throw new RuntimeException(e);
}
}
/**
* 发送邮件
*
* @param from 发送者邮箱
* @param to 接收者邮箱
* @param subject 主题
* @param mimeMultipart 主体部分
* @throws MessagingException
* @throws UnsupportedEncodingException
*/
private void sendMessage(String from, String to, String subject, MimeMultipart mimeMultipart) throws MessagingException, UnsupportedEncodingException {
if (isAnonymous) {
host = getMxHost(to, null);
port = "25";
}
// 获取 Session
String sslSocketFactory = SSLSocketFactory.class.getName();
Properties properties = new Properties();
properties.setProperty("mail.transport.protocol", "smtp");
properties.setProperty("mail.smtp.host", host);
properties.setProperty("mail.smtp.port", port);
properties.setProperty("mail.smtp.auth", String.valueOf(!isAnonymous));
properties.setProperty("mail.smtp.socketFactory.class", sslSocketFactory);
Session session = Session.getInstance(properties);
session.setDebug(debug);
// 建立连接并发送邮件
Transport transport = session.getTransport();
if (isAnonymous) {
transport.connect();
} else {
transport.connect(user, password);
}
MimeMessage mimeMessage = new MimeMessage(session);
mimeMessage.setFrom(new InternetAddress(from));
mimeMessage.setRecipients(Message.RecipientType.TO, to);
mimeMessage.setSubject(MimeUtility.encodeText(subject, CHARACTER_ENCODING, null));
mimeMessage.setContent(mimeMultipart);
mimeMessage.setHeader("X-Mailer", "JavaMail");
mimeMessage.setSentDate(new Date());
transport.sendMessage(mimeMessage, mimeMessage.getAllRecipients());
transport.close();
}
/**
* 根据邮箱获取对应的 MX 记录值
*
* @param email
* @param dns
* @return
*/
private String getMxHost(String email, String dns) {
final String regexp = "^(\\d+) (.+)\\.$";
try {
// 设置 DNS 服务器
if (dns == null) {
dns = "dns://";
} else {
dns = "dns://" + dns;
}
// 获取邮件地址中的域名
String[] emailArr = email.split("@");
if (emailArr.length != 2) {
throw new RuntimeException("email address error.");
}
String domain = emailArr[1];
// 通过 DNS 获取域名 MX 记录
Hashtable env = new Hashtable<>();
env.put(Context.INITIAL_CONTEXT_FACTORY, "com.sun.jndi.dns.DnsContextFactory");
env.put(Context.PROVIDER_URL, dns);
DirContext dirContext = new InitialDirContext(env);
Attributes attributes = dirContext.getAttributes(domain, new String[]{"MX"});
// 取出一组 MX 记录中第一个
Attribute mxAttribute = attributes.get("MX");
if (mxAttribute == null || mxAttribute.size() <= 0) {
return null;
}
NamingEnumeration> attributeAll = mxAttribute.getAll();
int mxPriority = Integer.MAX_VALUE;
String mxValue = null;
while (attributeAll.hasMore()) {
String mxs = (String) attributeAll.next();
int priority = Integer.parseInt(mxs.replaceAll(regexp, "$1"));
String value = mxs.replaceAll(regexp, "$2");
// 取优先级最高的值
if (priority < mxPriority) {
mxPriority = priority;
mxValue = value;
}
}
return mxValue;
} catch (NamingException e) {
return null;
}
}
private String encodeText(String text) {
try {
return MimeUtility.encodeText(text, CHARACTER_ENCODING, null);
} catch (UnsupportedEncodingException e) {
// ignore
}
return text;
}
public boolean isDebug() {
return debug;
}
public void setDebug(boolean debug) {
this.debug = debug;
}
}
```
依赖的包:
```
javax.mail
mail
1.4.7
```
分类:编程 关键词:邮件,匿名
评论(0) 浏览(1544)