/**
* Copyright 1996-2014 FoxBPM ORG.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
* @author kenshin
* @author ych
*/
package org.foxbpm.engine.impl.util;
import java.io.File;
import java.io.UnsupportedEncodingException;
import java.net.URL;
import java.util.Properties;
import java.util.Vector;
import javax.activation.DataHandler;
import javax.activation.FileDataSource;
import javax.mail.Address;
import javax.mail.Message;
import javax.mail.Multipart;
import javax.mail.Session;
import javax.mail.Transport;
import javax.mail.internet.AddressException;
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;
import org.foxbpm.engine.exception.FoxBPMException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
* <p>
* 邮件发送类
* </p>
* <p>
* 支持普通模式和HTML模式,可发送多个附件,支持SMTP服务器认证。<br>
* 基于javamail开发,使用时请将javamail包含在classpath系统变量中。
* </p>
* <p>
* <br>
* 使用说明:
* </p>
* <p>
* Mail mail=new Mail();
* </p>
* <p>
* mail.setXXX ....
* </p>
* <p>
* mail.send();<br>
* </p>
*
* @version 1.0
*/
@SuppressWarnings({ "rawtypes", "unchecked" })
public class MailUtil {
/**
* 日志
*/
private static final Logger LOGGER = LoggerFactory.getLogger(MailUtil.class);
/**
* 邮件地址标示
*/
public static final String MAIL_MARK = "@";
/**
* 普通模式
*/
public static final String MODE_TEXT = "text/plain;charset=gb2312";
/**
* HTML模式
*/
public static final String MODE_HTML = "text/html;charset=gb2312";
private Address[] to = null;
private Address[] cc = null;
private Address[] bcc = null;
private String from = "";
private String title = "";
private String content = "";
private String smtpHost = "";
private int smtpPort = 25;
private String content_type = MODE_TEXT;
private String htmlMailDesc = "";
private String smtpUser = "";
private String smtpPassword = "";
private boolean isAuthenticationSMTP = false;
private Vector vFiles = new Vector();
private Vector vURLs = new Vector();
public MailUtil() {
}
/**
* 设置SMTP服务器,使用默认端口
*
* @param server
* SMTP服务器IP
*/
public void setSmtpHost(String server) {
this.smtpHost = server;
}
/**
* 设置SMTP服务器
*
* @param server
* SMTP服务器IP
* @param port
* 端口
*/
public void setSmtpHost(String server, int port) {
this.smtpHost = server;
this.smtpPort = port;
}
/**
* 设置收件人地址
*
* @param aEmail
* 收件人Email地址
*/
public void setTo(String aEmail) {
String[] s = new String[1];
s[0] = aEmail;
this.to = getAddress(s);
}
/**
* 设置多个收件人地址
*
* @param Emails
* 收件人Email地址
*/
public void setTo(String[] Emails) {
this.to = getAddress(Emails);
}
/**
* 设置抄送地址
*
* @param aEmail
* 抄送地址
*/
public void setCC(String aEmail) {
String[] s = new String[1];
s[0] = aEmail;
this.cc = getAddress(s);
}
/**
* 设置多个抄送地址
*
* @param Emails
* 抄送地址
*/
public void setCC(String[] Emails) {
this.cc = getAddress(Emails);
}
/**
* 设置暗送地址
*
* @param Emails
* 暗送地址
*/
public void setBCC(String aEmail) {
String[] s = new String[1];
s[0] = aEmail;
this.bcc = getAddress(s);
}
/**
* 设置多个暗送地址
*
* @param Emails
* 暗送地址
*/
public void setBCC(String[] Emails) {
this.bcc = getAddress(Emails);
}
/**
* 设置发件人地址
*
* @param aEmail
* 发件人地址
*/
public void setFrom(String aEmail) {
this.from = aEmail;
}
/**
* 设置邮件主题
*
* @param mailTitle
* 邮件主题
*/
public void setSubject(String mailTitle) {
this.title = mailTitle;
}
/**
* 设置邮件文字内容
*
* @param mailContent
* 邮件文字内容
*/
public void setBody(String mailContent) {
this.content = mailContent;
}
/**
* 设置邮件字符类型
*
* @param contentType
* 请从静态变量TEXT和HTML中选择
*/
public void setContentType(String contentType) {
this.content_type = contentType;
}
/**
* 设置HTML格式邮件在一般模式下显示的说明
*
* @param desc
* 说明文字
*/
public void setHtmlMailDesc(String desc) {
this.htmlMailDesc = desc;
}
/**
* 设置SMTP服务器用户认证
*
* @param username
* 用户名
* @param password
* 密码
*/
public void setSmtpAuthentication(String username, String password) {
this.smtpUser = username;
this.smtpPassword = password;
this.isAuthenticationSMTP = true;
}
/**
* 添加附件
*
* @param afile
* 本地文件
*/
public void addAttachment(File afile) {
vFiles.add(afile);
}
/**
* 添加附件
*
* @param fileURL
* 文件URL
*/
public void addAttachment(URL fileURL) {
vURLs.add(fileURL);
}
/**
* 标示邮件是否附带附件
*
* @return
*/
public boolean hasAttachment() {
return vFiles.size() + vURLs.size() > 0;
}
/**
* 发送邮件
*/
public void send() {
LOGGER.debug("start send()");
try {
Properties server = new Properties();
if (StringUtil.isEmpty(this.smtpHost)) {
LOGGER.error("Please set SMTP host");
throw new NullPointerException("Please set SMTP host");
} else {
server.put("mail.smtp.host", this.smtpHost);
}
server.put("mail.smtp.port", String.valueOf(this.smtpPort));
if (this.isAuthenticationSMTP) {
server.put("mail.smtp.auth", "true");
}
Session conn = Session.getInstance(server, null);
MimeMessage msg = new MimeMessage(conn);
if (StringUtil.isEmpty(this.from)) {
LOGGER.error("Please set FROM address");
throw new NullPointerException("Please set FROM address");
} else {
msg.setFrom(new InternetAddress(this.from));
}
if (this.to != null) {
msg.setRecipients(Message.RecipientType.TO, this.to);
}
if (this.cc != null) {
msg.setRecipients(Message.RecipientType.CC, this.cc);
}
if (this.bcc != null) {
msg.setRecipients(Message.RecipientType.BCC, this.bcc);
}
try {
msg.setSubject(MimeUtility.encodeText(this.title));
} catch (UnsupportedEncodingException e) {
LOGGER.error("The mail header conversion failed", e);
throw new FoxBPMException("The mail header conversion failed", e);
}
if (!hasAttachment()) {
// 如果没有带附件
if (this.isHtmlModeMail()) {
// 是HTML格式的邮件
if (!this.hasHtmlDesc()) {
msg.setContent(this.content, this.content_type);
} else {
Multipart mp = new MimeMultipart();
MimeBodyPart mbp = null;
mbp = new MimeBodyPart();
mbp.setContent(this.content, this.content_type);
mp.addBodyPart(mbp);
mbp = new MimeBodyPart();
mbp.setContent(this.htmlMailDesc, MODE_TEXT);
mp.addBodyPart(mbp);
msg.setContent(mp);
}
} else {
// 是文本格式的邮件
msg.setText(this.content);
}
} else {
// 有附件
Multipart mp = new MimeMultipart();
MimeBodyPart mbp = null;
// 邮件正文
for (int i = 0; i < vFiles.size(); i++) {
mbp = new MimeBodyPart();
File file = (File) vFiles.get(i);
FileDataSource fds = new FileDataSource(file);
mbp.setDataHandler(new DataHandler(fds));
mbp.setFileName(file.getName());
mp.addBodyPart(mbp);
}
for (int i = 0; i < vURLs.size(); i++) {
mbp = new MimeBodyPart();
URL url = (URL) vURLs.get(i);
mbp.setDataHandler(new DataHandler(url));
mbp.setFileName(url.getFile());
mp.addBodyPart(mbp);
}
mbp = new MimeBodyPart();
mbp.setContent(this.content, this.content_type);
mp.addBodyPart(mbp);
if (this.isHtmlModeMail() && this.hasHtmlDesc()) {
mbp = new MimeBodyPart();
mbp.setContent(this.htmlMailDesc, MODE_TEXT);
mp.addBodyPart(mbp);
}
msg.setContent(mp);
}
msg.saveChanges();
if (this.isAuthenticationSMTP) {
Transport transport = conn.getTransport("smtp");
transport.connect(this.smtpHost, this.smtpUser, this.smtpPassword);
transport.sendMessage(msg, msg.getAllRecipients());
transport.close();
} else {
Transport.send(msg, msg.getAllRecipients());
}
} catch (javax.mail.internet.AddressException e) {
LOGGER.error("邮件地址出现异常", e);
throw new FoxBPMException(e.getMessage(), e);
} catch (javax.mail.MessagingException e) {
LOGGER.error("邮件消息出现异常", e);
throw new FoxBPMException(e.getMessage(), e);
}
LOGGER.debug("end send()");
}
/**
* 异步发送邮件
*/
public void asynSend() {
}
public boolean isValidEmailAddress(String email) {
if (StringUtil.isEmpty(email)) {
return false;
}
if (email.indexOf(MAIL_MARK) > 0) {
return !email.endsWith(MAIL_MARK);
}
return false;
}
private Address[] getAddress(String[] add) {
Address[] a = new Address[add.length];
for (int i = 0; i < add.length; i++) {
try {
a[i] = new InternetAddress(add[i]);
} catch (AddressException e) {
LOGGER.error("地址出现异常", e);
e.printStackTrace();
}
}
return a;
}
public boolean isHtmlModeMail() {
return this.content_type.equals(MODE_HTML);
}
public boolean hasHtmlDesc() {
if (!this.isHtmlModeMail()) {
return false;
}
return !StringUtil.isEmpty(this.htmlMailDesc);
}
}