import java.util.Date;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Properties;
import java.util.Set;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.InputStream;
import javax.activation.DataHandler;
import javax.activation.FileDataSource;
import javax.mail.Authenticator;
import javax.mail.Message;
import javax.mail.MessagingException;
import javax.mail.PasswordAuthentication;
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;
/**
* 使用SMTP协议发送电子邮件,可以发送以下五种类型的邮件:
* 1 简单文本邮件
* 2 简单HTML邮件
* 3 内嵌图片HTML邮件
* 4 混合组合邮件(带内嵌图片、附件、多收件人(显示邮箱姓名)、邮件优先级、阅读回执)
* 5 本地已经生成好的EML邮件文件
*
* @author liyinpeng
* @version 1.0
*/
public class JavaMailUtil {
private String host = "172.20.65.50"; // SMTP邮件服务器
private int port = 25; // SMTP邮件服务器端口号
private String protocol = "smtp"; // 邮件发送协议
private boolean isAuth = true; // 是否要求身份认证
private boolean isDebugMod = true; // 是否启用调试模式(启用调试模式可打印客户端与服务器交互过程时一问一答的响应消息
private String charSet = "utf-8"; // 编码方式
private String username; // 用户名
private String password; // 用户密码
private Authenticator authenticator; // 邮件验证类
private Session session; // 邮件会话
private MimeMessage message; // 邮件消息
/**
* 构造函数
* @param username 用户名
* @param password 用户密码
*/
public JavaMailUtil(String username, String password) {
this.username = username;
this.password = password;
if(isAuth) {
authenticator = new Authenticator() {
protected PasswordAuthentication getPasswordAuthentication() {
return new PasswordAuthentication(getUsername(), getPassword());
}
};
}
// 创建一个系统属性来设置属性信息
Properties props = new Properties();
props.put("mail.transport.protocol", protocol);
props.put("mail.smtp.host", host);
props.put("mail.smtp.port", port);
props.put("mail.debug", isDebugMod);
props.put("mail.smtp.auth", isAuth);
// 创建Session实例对象
session = Session.getDefaultInstance(props, authenticator);
}
/**
* 简单文本邮件的发送
* @param from 发件人
* @param to 收件人
* @param subject 邮件标题
* @param content 邮件内容
* @throws Exception
*/
public void setSimpleMail(String from, String[] to, String subject, String content) throws Exception {
// 创建MimeMessage实例对象
message = new MimeMessage(session);
// 设置邮件发件人
if(from != null) {
message.setFrom(new InternetAddress(from));
}
// 设置邮件收件人
InternetAddress[] tos = new InternetAddress[to.length];
if(to != null) {
for(int i = 0; i < to.length; i++) {
tos[i] = new InternetAddress(to[i]);
}
message.setRecipients(Message.RecipientType.TO, tos);
}
// 设置邮件主题
if(subject != null) {
message.setSubject(MimeUtility.encodeWord(subject, charSet, "B"));
}
// 设置邮件发送时间
message.setSentDate(new Date());
// 设置邮件正文
message.setText(content, charSet);
// 保存并生成最终的邮件内容
message.saveChanges();
}
/**
* 简单HTML邮件的发送
* @param from 发件人
* @param to 收件人
* @param subject 邮件标题
* @param content 邮件内容
* @throws Exception
*/
public void setHtmlMail(String from, String[] to, String subject, String content) throws Exception {
// 创建MimeMessage实例对象
message = new MimeMessage(session);
// 设置邮件发件人
if(from != null) {
message.setFrom(new InternetAddress(from));
}
// 设置邮件收件人
InternetAddress[] tos = new InternetAddress[to.length];
if(to != null) {
for(int i = 0; i < to.length; i++) {
tos[i] = new InternetAddress(to[i]);
}
message.setRecipients(Message.RecipientType.TO, tos);
}
// 设置邮件主题
if(subject != null) {
message.setSubject(MimeUtility.encodeWord(subject, charSet, "B"));
}
// 设置邮件发送时间
message.setSentDate(new Date());
// 设置邮件正文
message.setContent(content, "text/html; charset=" + charSet);
// 保存并生成最终的邮件内容
message.saveChanges();
}
/**
* 内嵌图片HTML邮件
* 发送带图片的邮件一般有2种方式:
* 1 用img标签将src直接指向图片所在服务器地址如:邮件内容肯定是用<img src="http://xxx.xxx/xx/xx.jpg"></img>
* 2 将图片放到邮件中并起个ID号,然后在邮件内容部分引用它(采用)
* @param from 发件人
* @param to 收件人
* @param subject 邮件标题
* @param content 邮件内容
* @param imageMap 内嵌图片
* @throws Exception
*/
public void setHtmlWithImgMail(String from, String[] to, String subject, String content, Map<String,String> imageMap) throws Exception {
// 创建MimeMessage实例对象
message = new MimeMessage(session);
// 设置邮件发件人
if(from != null) {
message.setFrom(new InternetAddress(from));
}
// 设置邮件收件人
InternetAddress[] tos = new InternetAddress[to.length];
if(to != null) {
for(int i = 0; i < to.length; i++) {
tos[i] = new InternetAddress(to[i]);
}
message.setRecipients(Message.RecipientType.TO, tos);
}
// 设置邮件主题
if(subject != null) {
message.setSubject(MimeUtility.encodeWord(subject, charSet, "B"));
}
// 设置邮件发送时间
message.setSentDate(new Date());
// 创建一个MIME子类型为"related"的MimeMultipart对象 设置为整个邮件的内容
MimeMultipart mp = new MimeMultipart("related");
message.setContent(mp);
// 设置内嵌图片邮件体
if (imageMap != null && imageMap.size() > 0) {
Set<Entry<String, String>> set = imageMap.entrySet();
Iterator iterator = set.iterator();
while(iterator.hasNext()) {
Entry<String, String> entry = (Entry<String, String>)iterator.next();
// 创建一个表示图片资源的MimeBodyPart对象,将将它加入到前面创建的MimeMultipart对象中
MimeBodyPart imagePart = new MimeBodyPart();
mp.addBodyPart(imagePart);
//创建用于保存图片的MimeBodyPart对象,并将它保存到MimeMultipart中
FileDataSource fds = new FileDataSource(entry.getValue());//图片所在的目录的绝对路径
imagePart.setDataHandler(new DataHandler(fds));
imagePart.setContentID(entry.getKey()); //cid的值
}
}
// 创建一个表示正文的MimeBodyPart对象,并将它加入到前面创建的MimeMultipart对象中
MimeBodyPart htmlPart = new MimeBodyPart();
mp.addBodyPart(htmlPart);
// 创建一个MIME子类型为"alternative"的MimeMultipart对象,并作为前面创建的htmlPart对象的邮件内容
MimeMultipart htmlMultipart = new MimeMultipart("alternative");
// 创建一个表示html正文的MimeBodyPart对象
MimeBodyPart htmlBodypart = new MimeBodyPart();
// 其中cid=test.jpg是引用邮件内部的图片,即imagePart.setContentID("test.jpg");方法所保存的图片
htmlBodypart.setContent(content, "text/html;charset="+charSet);
htmlMultipart.addBodyPart(htmlBodypart);
htmlPart.setContent(htmlMultipart);
// 保存并生成最终的邮件内容
message.saveChanges();
}
/**
* 混合组合邮件
* @param from 发件人
* @param to 收件人
* @param subject 邮件标题
* @param content 邮件内容
* @param imageMap 内嵌图片
* @param attList 附件
* @throws Exception
*/
public void setMultipleMail(String from, String[] to, String subject, String content, Map<String,String> imageMap, List<String> attList) throws Exception {
// 创建MimeMessage实例对象
message = new MimeMessage(session);
// 设置邮件发件人
if(from != null) {
message.setFrom(new InternetAddress(from));
}
// 设置邮件收件人
InternetAddress[] tos = new InternetAddress[to.length];
if(to != null) {
for(int i = 0; i < to.length; i++) {
tos[i] = new InternetAddress(to[i]);
}
message.setRecipients(Message.RecipientType.TO, tos);
}
/**
message.setRecipients(Message.RecipientType.TO,
new Address[] {
// 参数1:邮箱地址,参数2:姓名(在客户端收件只显示姓名,而不显示邮件地址),参数3:姓名中文字符串编码
new InternetAddress("[email protected]", "张三", charSet),
new InternetAddress("[email protected]", "李四", charSet),
}
);*/
// 设置邮件主题
if(subject != null) {
message.setSubject(MimeUtility.encodeWord(subject, charSet, "B"));
}
// 设置邮件发送时间
message.setSentDate(new Date());
// 设置优先级(1:紧急 3:普通 5:低)
message.setHeader("X-Priority", "1");
// 要求阅读回执(收件人阅读邮件时会提示回复发件人,表明邮件已收到,并已阅读)
message.setHeader("Disposition-Notification-To", from);
// (附件+邮件体)创建一个MIME子类型为"mixed"的MimeMultipart对象,表示这是一封混合组合类型的邮件
MimeMultipart mailContent = new MimeMultipart("mixed");
message.setContent(mailContent);
// (附件)创建保存附件的MimeBodyPart对象,并加入附件内容和相应的信息
for (int i = 0;i < attList.size(); i++) {
MimeBodyPart attachPart = new MimeBodyPart();
mailContent.addBodyPart(attachPart);
FileDataSource fsd=new FileDataSource(attList.get(i));
attachPart.setDataHandler(new DataHandler(fsd));
attachPart.setFileName(fsd.getName());
}
// 邮件体(邮件混合体)
MimeBodyPart mailBody = new MimeBodyPart();
mailContent.addBodyPart(mailBody);
// 邮件混合体(内嵌图片+html文本)
MimeMultipart mp = new MimeMultipart("related");
mailBody.setContent(mp);
// 内嵌图片
if (imageMap != null && imageMap.size() > 0) {
Set<Entry<String, String>> set = imageMap.entrySet();
Iterator iterator = set.iterator();
while(iterator.hasNext()) {
Entry<String, String> entry = (Entry<String, String>)iterator.next();
// 创建一个表示图片资源的MimeBodyPart对象,将将它加入到前面创建的MimeMultipart对象中
MimeBodyPart imagePart = new MimeBodyPart();
mp.addBodyPart(imagePart);
//创建用于保存图片的MimeBodyPart对象,并将它保存到MimeMultipart中
FileDataSource fds = new FileDataSource(entry.getValue());//图片所在的目录的绝对路径
imagePart.setDataHandler(new DataHandler(fds));
imagePart.setContentID(entry.getKey()); //cid的值
}
}
// html文本
MimeBodyPart htmlPart = new MimeBodyPart();
mp.addBodyPart(htmlPart);
MimeMultipart htmlMultipart = new MimeMultipart("alternative");
htmlPart.setContent(htmlMultipart);
MimeBodyPart htmlContent = new MimeBodyPart();
htmlContent.setContent(content, "text/html;charset="+charSet);
htmlMultipart.addBodyPart(htmlContent);
// 保存并生成最终的邮件内容
message.saveChanges();
}
/**
* 将邮件内容生成eml文件
* @param message 邮件内容
* @param Exception
*/
public File buildEmlFile(Message message) throws Exception {
File file = new File("D:\\" + MimeUtility.decodeText(message.getSubject())+".eml");
message.writeTo(new FileOutputStream(file));
return file;
}
/**
* 发送本地已经生成好的email文件
* @param eml 本地生成好的EML邮件文件
* @param Exception
*/
public void sendMailForEml(File eml) throws Exception {
// 获得邮件内容,即发生前生成的eml文件
InputStream is = new FileInputStream(eml);
message = new MimeMessage(session,is);
}
/**
* 发送邮件
*/
public void send() {
try {
// 创建Transport实例对象
Transport transport = session.getTransport();
// 打开连接
transport.connect();
// 将message对象传递给transport对象,将邮件发送出去
transport.sendMessage(message, message.getAllRecipients());
// 关闭连接
transport.close();
} catch (MessagingException e) {
e.printStackTrace();
}
}
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
public static void main(String[] args) throws Exception {
//简单文本邮件
// JavaMailUtil javaMail1 = new JavaMailUtil("[email protected]", "liyinpeng");
// javaMail1.setSimpleMail("[email protected]", new String[]{"[email protected]"}, "简单文本邮件", "内容");
// javaMail1.send();
//简单HTML邮件
// JavaMailUtil javaMail2 = new JavaMailUtil("[email protected]", "liyinpeng");
// javaMail2.setHtmlMail("[email protected]", new String[]{"[email protected]"}, "简单HTML邮件", "<h1>内容</h1>");
// javaMail2.send();
//内嵌图片的HTML邮件
// JavaMailUtil javaMail3 = new JavaMailUtil("[email protected]", "liyinpeng");
// String content = "<span style='color:red;'>内嵌图片的HTML邮件<img src=\"cid:IMG000001\" /></span><br>第二张<img src=\"cid:IMG000002\" />";
// Map<String,String> imageMap = new HashMap<String,String>();//存放内嵌图片的cid和绝对路径
// imageMap.put("IMG000001", "E:\\logo.gif");
// imageMap.put("IMG000002", "E:\\car.jpg");
// javaMail3.setHtmlWithImgMail("[email protected]", new String[]{"[email protected]"}, "内嵌图片HTML邮件", content, imageMap);
// javaMail3.send();
//组合混合邮件(内嵌图片+附件)
// JavaMailUtil javaMail4 = new JavaMailUtil("[email protected]", "liyinpeng");
// String content = "<span style='color:red;'>内嵌图片的HTML邮件<img src=\"cid:IMG000001\" /></span><br>第二张<img src=\"cid:IMG000002\" />";
// Map<String,String> imageMap = new HashMap<String,String>();//存放内嵌图片的cid和绝对路径
// imageMap.put("IMG000001", "E:\\logo.gif");
// imageMap.put("IMG000002", "E:\\car.jpg");
// List<String> attList = new ArrayList<String>();
// attList.add("E:\\111.docx");
// attList.add("E:\\222.txt");
// javaMail4.setMultipleMail("[email protected]", new String[]{"[email protected]"}, "混合组合邮件", content, imageMap, attList);
// javaMail4.send();
//发送本地生成的EML邮件文件
// JavaMailUtil javaMail5 = new JavaMailUtil("[email protected]", "liyinpeng");
// File emlFile = new File("D:\\混合组合邮件.eml");
// javaMail5.sendMailForEml(emlFile);
// javaMail5.send();
/**
+------------------------- multipart/mixed ----------------------------+
| |
| +----------------- multipart/related ------------------+ |
| | | |
| | +----- multipart/alternative ------+ +----------+ | +------+ |
| | | | | 内嵌资源 | | | 附件 | |
| | | +------------+ +------------+ | +----------+ | +------+ |
| | | | 纯文本正文 | | 超文本正文 | | | |
| | | +------------+ +------------+ | +----------+ | +------+ |
| | | | | 内嵌资源 | | | 附件 | |
| | +----------------------------------+ +----------+ | +------+ |
| | | |
| +------------------------------------------------------+ |
| |
+----------------------------------------------------------------------+
*/
}
}