不知不觉到了邮件版本的4.0,渐渐更新完善的方法,此次更新加入了读取properties,将方法设置为静态,去除getset方法等等。
package com.geecke.tools.mail;
import java.io.Serializable;
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.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;
/**
* 邮件发送器
*
* JavaMail 版本: 1.6.0 JDK 版本: JDK 1.8
*
* @author iu_chang
* @version 4.0
*
*/
public final class MailTool implements Serializable {
private static final long serialVersionUID = 1L;
/** 配置文件路径 */
private static final String PROPERTIES_PAHT = "mail.properties";
/** 发件人账号 */
private static String Account;
/** 发件人名称 */
private static String Name;
/** 发件人密码或授权码 */
private static String Password;
/** SMTP服务器地址 */
private static String Host;
/** 邮件编码 */
private static String Encoding;
/** 发送方信息 */
private static InternetAddress Sender = null;
static {
// 属性集
Properties prop = new Properties();
try {
// 读取配置文件的邮件发送方信息
prop.load(new InputStreamReader(MailTool.class.getClassLoader().getResourceAsStream(PROPERTIES_PAHT),
"UTF-8"));
Account = prop.getProperty("mail.account");
Name = prop.getProperty("mail.name");
Password = prop.getProperty("mail.paddword");
Host = prop.getProperty("mail.host");
Encoding = prop.getProperty("mail.encoding");
// 初始化时创建发送方信息,即默认为配置的账号发送
Sender = new InternetAddress(Account, Name, Encoding);
} catch (Exception e) {
System.out.println("======> 邮件发送器初始化错误 <======");
}
}
/** 该类作为工具类,无法通过new关键字构建 */
private MailTool() {
}
/**
* 得到收件人信息
*
* @param receiver
* 收件人地址
* @return InternetAddress[] 返回的收件人信息数组
* @throws Exception
* 当什么都没传过来时会抛出收件人为空的异常
*/
public static InternetAddress[] getReceivers(String... receiver) throws Exception {
// 如果没有传入收件人
if (receiver.length < 0) {
throw new RuntimeException("收件人为空");
}
// 将字符串数组转为收件人数组
InternetAddress[] receiverArray = new InternetAddress[receiver.length];
for (int i = 0; i < receiverArray.length; i++) {
receiverArray[i] = new InternetAddress(receiver[i]);
}
return receiverArray;
}
/**
* 设置发送人信息
*
* @param accound
* 发送人账号
* @param name
* 发送人名称
* @param password
* 发送人密码或授权码
* @param host
* 发送人邮件服务器
* @param encoding
* 发送人编码
* @throws UnsupportedEncodingException
*/
public static void setSender(String account, String name, String password, String host, String encoding)
throws UnsupportedEncodingException {
Account = account;
Name = name;
Password = password;
Host = host;
Encoding = encoding;
Sender = new InternetAddress(Account, Name, Encoding);
}
/**
* 设置发送人信息
*
* @param accound
* 发送人账号
* @param name
* 发送人名称
* @param password
* 发送人密码或授权码
* @param host
* 发送人邮件服务器
* @throws UnsupportedEncodingException
*/
public static void setSender(String account, String name, String password, String host)
throws UnsupportedEncodingException {
Account = account;
Name = name;
Password = password;
Host = host;
Sender = new InternetAddress(Account, Name, Encoding);
}
/**
* 设置发送人信息
*
* @param accound
* 发送人账号
* @param name
* 发送人名称
* @param password
* 发送人密码或授权码
* @throws UnsupportedEncodingException
*/
public static void setSender(String account, String name, String password) throws UnsupportedEncodingException {
Account = account;
Name = name;
Password = password;
Sender = new InternetAddress(Account, Name, Encoding);
}
/**
* 根据内容获取MimeBodyPart
*
* @param content
* 文本内容,如果引用本地文件请使用src='cid:image_fairy_tail'的形式<br>
* 网络文件则忽略images参数
* @param isCode
* 是否为html代码<br>
* 如果为false,则发送纯文本,且files参数无效
* @param files
* 本地图片加载,数组第一个元素为文件全路径,第二个元素为cid名称,cid是content的引用<br>
* 例如在content参数中使用了 img src='cid:my_image' / <br>
* 则该图片的地址是此参数的第二个元素的名称,如{"C:/photo.png","my_image"}
*
* @return 单个part节点
* @throws Exception
*/
public static MimeBodyPart getPart(String content, Boolean isCode, String[]... files) throws Exception {
MimeBodyPart part = new MimeBodyPart();
if (!isCode) {// 如果为false,则发送纯文本
part.setContent(content, "text/plain;charset=" + Encoding);
return part;
}
// 新建一个大节点
MimeMultipart mimeMultipart = new MimeMultipart();
// 解析images生成part
for (String[] file : files) {
// 新建文件节点
MimeBodyPart filePart = new MimeBodyPart();
// 读入本地文件
DataHandler data = new DataHandler(new FileDataSource(file[0]));
// 将文件数据添加到文件节点
filePart.setDataHandler(data);
// 为文件节点设置一个唯一编号(在content将引用该ID)
filePart.setContentID(file[1]);
// 将该文件添加至大节点
mimeMultipart.addBodyPart(filePart);
}
// 新建文本节点
MimeBodyPart textPart = new MimeBodyPart();
// 将文本加入至节点
textPart.setContent(content, "text/html;charset=" + Encoding);
// 将节点整合到大节点
mimeMultipart.addBodyPart(textPart);
// 设置节点关系为关联
mimeMultipart.setSubType("related");
// 将大节点封装成节点
part.setContent(mimeMultipart);
return part;
}
/**
* 获取单个附件节点
*
* @param file
* 附件全路径
* @param name
* 附件名,传入null则使用file的名称
* @return 单个part节点
* @throws Exception
*/
public static MimeBodyPart getPart(String file, String name) throws Exception {
// 创建附件节点
MimeBodyPart part = new MimeBodyPart();
// 读取本地文件
DataHandler data = new DataHandler(new FileDataSource(file));
// 将附件数据添加到附件节点
part.setDataHandler(data);
// 设置附件名称(需要编码)
if (name == null || "".equals(name)) {// 如果附件名为null或"",则使用file文件名
part.setFileName(MimeUtility.encodeText(data.getName()));
return part;
}
part.setFileName(MimeUtility.encodeText(name));
return part;
}
/**
* 创建一封邮件
*
* @param session
* 用于和邮件服务器交互的会话
* @param subject
* 邮件主题
* @param recipientType
* 发送类型:<br>
* 普通:RecipientType.TO<br>
* 抄送:RecipientType.CC<br>
* 密送:RecipientType.BCC
* @param receivers
* 收件人邮箱数组
* @param parts
* 邮件内容节点
* @return 创建好的邮件对象
* @throws Exception
*/
private static MimeMessage createMimeMessage(Session session, String subject, RecipientType recipientType,
InternetAddress[] receivers, MimeBodyPart... parts) throws Exception {
if (receivers.length < 0) {
throw new RuntimeException("收件人为空");
}
// 创建邮件对象
MimeMessage message = new MimeMessage(session);
// 设置发件人
message.setFrom(Sender);
// 设置收件人
for (InternetAddress receiver : receivers) {
message.addRecipient(recipientType, receiver);
}
// 设置邮件主题
message.setSubject(subject, Encoding);
// 创建大节点
MimeMultipart multipart = new MimeMultipart();
// 将传入的内容节点依次添加进大节点
for (MimeBodyPart part : parts) {
multipart.addBodyPart(part);
}
// 设置节点关系,不设置则为混合:mixed,可以设置为关联:related
multipart.setSubType("mixed");
// 设置邮件内容
message.setContent(multipart);
// 设置发件时间
message.setSentDate(new Date());
// 保存所有设置
message.saveChanges();
return message;
}
/**
* 发送邮件
*
* @param receivers
* 收件人数组,使用getReceivers()方法获得
* @param subject
* 邮件主题
* @param recipientType
* 发送类型<br>
* 普通:RecipientType.TO<br>
* 抄送:RecipientType.CC<br>
* 密送:RecipientType.BCC
* @param parts
* 节点,使用getPart()方法获得
* @throws Exception
*/
public static void send(InternetAddress[] receivers, String subject, RecipientType recipientType,
MimeBodyPart... parts) throws Exception {
// 创建会话参数
Properties props = new Properties();
// 设置使用的协议(JavaMail规范要求)
props.setProperty("mail.transport.protocol", "smtp");
// 设置发件人的邮箱的SMTP服务器地址
props.setProperty("mail.smtp.host", Host);
// 设置需要请求认证
props.setProperty("mail.smtp.auth", "true");
// 根据会话参数创建会话对象, 用于和邮件服务器交互
Session session = Session.getInstance(props);
// 设置为debug模式,可以查看详细的发送 log
session.setDebug(true);
// 创建一封邮件
MimeMessage message = createMimeMessage(session, subject, recipientType, receivers, parts);
// 保存到本地查看
// message.writeTo(FileOutputStream);
// 根据Session获取邮件传输对象
Transport transport = session.getTransport();
// 使用邮箱账号和密码连接邮件服务器
// 这里认证的邮箱必须与message中的发件人邮箱一致,否则报错
transport.connect(Account, Password);
// 发送邮件,发到所有的收件地址,message.getAllRecipients()获取到的是在创建邮件对象时添加发送类型
transport.sendMessage(message, message.getAllRecipients());
// 关闭连接
transport.close();
}
}