SMTP邮件群发工具类(支持Sina、Sohu、Gmail、QQ等SMTP邮件服务器
写完上个demo后,甚感代码很丑陋,在网友的建议下,于是我马不停蹄的开始重构封装我的代码,现整了个发送邮件的工具类,分享给大家:
package com.lxw.demo;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.UnsupportedEncodingException;
import java.util.Date;
import java.util.Properties;
import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import javax.activation.DataHandler;
import javax.activation.DataSource;
import javax.activation.FileDataSource;
import javax.mail.Address;
import javax.mail.Authenticator;
import javax.mail.MessagingException;
import javax.mail.Part;
import javax.mail.PasswordAuthentication;
import javax.mail.Session;
import javax.mail.Transport;
import javax.mail.URLName;
import javax.mail.Message.RecipientType;
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 javax.mail.util.ByteArrayDataSource;
import com.lxw.test.Test5;
import com.sun.mail.smtp.SMTPTransport;
/**
* SMTP邮件群发工具类(支持Sina、Sohu、Gmail、QQ等SMTP邮件服务器)
* @author Lanxiaowei
* @createTime 2011-12-4 下午07:06:18
*/
public class MailUtil {
/**邮件回话*/
private Session session;
/**线程池*/
ThreadPoolExecutor executor = null;
/**是否需要重新加载Properties资源*/
public static boolean cache_reload = true;
private static Properties properties;
public Properties getProperties() {
return properties;
}
public void setProperties(Properties properties) {
this.properties = properties;
}
{
//默认队列同时运行个数5
executor = new ThreadPoolExecutor(1, Integer.MAX_VALUE, 60,TimeUnit.SECONDS, new ArrayBlockingQueue<Runnable>(5));
}
/**
* 加载properties资源并缓存
* @param filePath properties资源文件路径
* @return Properties properties资源
*/
public static Properties cacheLoadProperties(String filePath){
if(null == properties || cache_reload){
properties = new Properties();
InputStream is = MailUtil.class.getResourceAsStream(filePath);
try {
properties.load(is);
} catch (IOException e) {
throw new RuntimeException("the properties loaded not found");
}
}
cache_reload = false;
return properties;
}
/**
* 线程同步创建邮件会话Session
*/
private synchronized void createSession() {
Properties mailProps = this.cacheLoadProperties("");
/*//gmail 邮件会话特殊参数
if("smtp.gmail.com".equals(host)){
mailProps.setProperty("mail.smtp.socketFactory.class","javax.net.ssl.SSLSocketFactory");
mailProps.setProperty("mail.smtp.socketFactory.fallback", "false");
mailProps.setProperty("mail.smtp.socketFactory.port",String.valueOf(this.port));
}*/
//创建邮件会话
Session session = null;
if(!Boolean.valueOf(properties.getProperty("mail.smtp.auth"))){
session = Session.getDefaultInstance(properties, null);
} else{
session = Session.getInstance(properties,new Authenticator(){
@Override
/**
* 服务器端身份验证
*/
protected PasswordAuthentication getPasswordAuthentication() {
return new PasswordAuthentication(
properties.getProperty("userName"),
properties.getProperty("passWord")
);
}
});
}
//关闭调试模式(编码测试阶段建议打开)
session.setDebug(false);
}
/**
* 设置发件人
* @param message 复合邮件消息对象
* @param fromMail 发件人邮箱地址
* @param fromName 发件人姓名
*/
private void setSender(MimeMessage message,String fromMail,String fromName){
if(null == message || null == fromMail){
return;
}
try {
Address from = new InternetAddress(fromMail,fromName);
message.setFrom(from);
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
} catch (MessagingException e) {
e.printStackTrace();
}
}
/**
* 设置回复人
* @param message 复合邮件消息对象
* @param replyEmail 回复人邮箱地址
* @param replyName 回复人姓名
*/
private void setReplier(MimeMessage message,String[] replyEmail,String[] replyName){
if(null == message || null == replyEmail){
return;
}
try {
Address reply[] = new Address[replyEmail.length];
for(int i = 0; i < replyEmail.length; i++){
if(isNotNull(replyName)){
reply[i] = new InternetAddress(replyEmail[i],replyName[i],properties.getProperty("charset"));
} else{
reply[i] = new InternetAddress(replyEmail[i],"",properties.getProperty("charset"));
}
}
if(isNotNull(reply)){
message.setReplyTo(reply);
}
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
} catch (MessagingException e) {
e.printStackTrace();
}
}
/**
* 设置收件人
* @param message 复合邮件消息对象
* @param toMail 收件人邮箱地址
* @param toName 收件人姓名
*/
private void setReceiver(MimeMessage message,String[] toMail,String[] toName){
setMessage(message, toMail, toName, RecipientType.TO);
}
/**
* 设置抄送人
* @param message 复合邮件消息对象
* @param ccMail 抄送人邮箱地址
* @param ccName 抄送人姓名
*/
private void setCC(MimeMessage message,String[] ccMail,String[] ccName){
setMessage(message, ccMail, ccName, RecipientType.CC);
}
/**
* 设置密送人
* @param message 复合邮件消息对象
* @param bccMail 密送人邮箱地址
* @param bccName 密送人姓名
*/
private void setBCC(MimeMessage message,String[] bccMail,String[] bccName){
setMessage(message, bccMail, bccName, RecipientType.BCC);
}
/**
* 设置收件人、抄送人、密送人
* @param message 复合邮件消息对象
* @param mails 邮箱地址
* @param names 姓名
*/
private void setMessage(MimeMessage message,String[] mails,String[] names,RecipientType type){
if(null == message || null == mails || null == type){
return;
}
try {
Address to[] = new Address[mails.length];
for(int i = 0; i < mails.length; i++){
if(isNotNull(names)){
to[i] = new InternetAddress(mails[i],names[i],properties.getProperty("charset"));
} else{
to[i] = new InternetAddress(mails[i],"",properties.getProperty("charset"));
}
}
if(isNotNull(to)){
message.setRecipients(type, to);
}
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
} catch (MessagingException e) {
e.printStackTrace();
}
}
/**
* 创建邮件消息对象
* @return MimeMessage
*/
private MimeMessage createMimeMessage() {
if (null == session) {
createSession();
}
return new MimeMessage(session);
}
/**
* 发送邮件信息
*/
private void sendMessage(MimeMessage message){
if (null != message) {
executor.execute(new SendEmailThread(message));
} else {
throw new RuntimeException("Cannot add null email message to queue.");
}
}
/**
* 发送邮件(支持群发)(重载,方便调用)
* @param mimeMessage 消息头对象
* @param mailBean 自定义的邮件bean
* @return boolean 发送是否成功
*/
private boolean sendMail(MailBean mailBean){
return sendMail(null,mailBean);
}
/**
* 发送邮件(支持群发)
* @param mimeMessage 消息头对象
* @param mailBean 自定义的邮件bean
* @return boolean 发送是否成功
*/
private boolean sendMail(MimeMessage mimeMessage,MailBean mailBean){
if(null == mailBean){
return false;
}
if (null == mimeMessage) {
mimeMessage = createMimeMessage();
}
try {
//设置发件人
setSender(mimeMessage,mailBean.getFromMail(),mailBean.getFromName());
//设置回复人
setReplier(mimeMessage,mailBean.getReplyEmail(),mailBean.getReplyName());
//设置收件人
setReceiver(mimeMessage, mailBean.getToMail(), mailBean.getToName());
//设置抄送人
setCC(mimeMessage, mailBean.getCcMail(), mailBean.getCcName());
//设置密送人
setBCC(mimeMessage, mailBean.getBccMail(), mailBean.getBccName());
//设置邮件主题
mimeMessage.setSubject(mailBean.getSubject(), properties.getProperty("charset"));
//设置发送时间
mimeMessage.setSentDate(new Date());
MimeMultipart mimeMultipart = null;
//若是html格式邮件
if(null != mailBean.getMailFormat()&& "html".equals(mailBean.getMailFormat())){
mimeMultipart = new MimeMultipart("mixed");
createMailMain(
mimeMultipart,
mailBean.getAttchmentFileNames(),
mailBean.getContent(),
mailBean.getPicNames()
);
} else{ //纯文本格式邮件
//选择关系
mimeMultipart = new MimeMultipart("alternative");
MimeBodyPart textPart = new MimeBodyPart();
textPart.setText(mailBean.getContent(), properties.getProperty("charset"));
textPart.setDisposition(Part.INLINE);
mimeMultipart.addBodyPart(textPart);
}
mimeMessage.setContent(mimeMultipart);
mimeMessage.setDisposition(Part.INLINE);
//存储邮件信息
mimeMessage.saveChanges();
//线程发送邮件
sendMessage(mimeMessage);
} catch (Exception e) {
e.printStackTrace();
return false;
}
return true;
}
/**
* 创建邮件主体
* @param mimeMultipart 邮件复合主体部分
* @param attchmentFileNames 附件列表
* @param content 邮件正文部分
* @param picNames 插入图片列表
*/
private void createMailMain(MimeMultipart mimeMultipart,String[] attchmentFileNames,String content,String[] picNames){
if(null == mimeMultipart){
return;
}
try {
mimeMultipart.setSubType("mixed");
MimeBodyPart contentPart = new MimeBodyPart();
//添加附件
createAttchementPart(mimeMultipart,attchmentFileNames);
//创建邮件正文部分
CreateBodyPart(contentPart,content,picNames);
mimeMultipart.addBodyPart(contentPart);
} catch (Exception e) {
e.printStackTrace();
}
}
/**
* 创建邮件正文部分
* @param content 邮件正文部分
* @param picNames 插入图片列表
*/
private void CreateBodyPart(MimeBodyPart contentPart,String content,String[] picNames){
if(null == contentPart){
return;
}
try {
MimeMultipart bodyMultipart = new MimeMultipart("related");
//HTML
CreateHTMLPart(bodyMultipart,content);
//图片资源
CreatePicPart(bodyMultipart,picNames);
contentPart.setContent(bodyMultipart);
} catch (Exception e) {
e.printStackTrace();
}
}
/**
* 创建邮件HTML部分
* @param mimeMultipart 邮件正文部分
* @param content HTML内容
*/
private void CreateHTMLPart(MimeMultipart bodyMultipart,String content){
if(null == bodyMultipart || null == content){
return;
}
try {
bodyMultipart.setSubType("related");
MimeBodyPart htmlPart = new MimeBodyPart();
htmlPart.setContent(content, "text/html;charset=utf-8");
bodyMultipart.addBodyPart(htmlPart);
} catch (Exception e) {
e.printStackTrace();
}
}
/**
* 创建邮件嵌入图片资源部分
* @param mimeMultipart 邮件正文部分
* @param picNames 插入图片列表
*/
private void CreatePicPart(MimeMultipart bodyMultipart,String[] picNames){
if(null == bodyMultipart || !isNotNull(picNames)){
return;
}
try {
//关联类型
bodyMultipart.setSubType("related");
String fileName = "";
for (int i = 0; i < picNames.length; i++) {
MimeBodyPart picPart = new MimeBodyPart();
byte[] imgbytes = getBytesFromFile(new File(picNames[i]));
fileName = getFileName(picNames[i]);
DataSource picds = new ByteArrayDataSource(imgbytes,"application/octet-stream");
DataHandler picDataHandler = new DataHandler(picds);
picPart.setDataHandler(picDataHandler);
picPart.setFileName(fileName);
picPart.setHeader("Content-ID", "IMG" + fileName.substring(0, fileName.lastIndexOf(".")));
bodyMultipart.addBodyPart(picPart);
}
} catch (Exception e) {
e.printStackTrace();
}
}
/**
* 创建邮件附件部分
* @param mimeMultipart 邮件复合主体部分
* @param attchmentFileNames 附件列表
*/
private void createAttchementPart(MimeMultipart mimeMultipart,String[] attchmentFileNames){
if(null == mimeMultipart || !isNotNull(attchmentFileNames)){
return;
}
try {
//复合类型
mimeMultipart.setSubType("mixed");
for (int i = 0; i < attchmentFileNames.length; i++) {
MimeBodyPart attch = new MimeBodyPart();
DataSource ds = new FileDataSource(attchmentFileNames[i]);
DataHandler dataHandler = new DataHandler(ds);
attch.setDataHandler(dataHandler);
if(isNotNull(attchmentFileNames)){
attch.setFileName(MimeUtility.encodeText(getFileName(attchmentFileNames[i])));
}
mimeMultipart.addBodyPart(attch);
}
} catch (Exception e) {
e.printStackTrace();
}
}
/**
* 判断数组是否为空(包含null和数组元素个数为0)
*/
private boolean isNotNull(Object[] objects){
return null != objects && objects.length != 0;
}
/**
* 把email地址转换成友好的中文姓名显示
* @param email 邮箱地址
* @param name 中文姓名
* @throws UnsupportedEncodingException
*/
private String getFriendlyName(String email,String name) throws UnsupportedEncodingException{
if(null == name || name.trim().equals("")){
return email;
}
StringBuffer buffer = new StringBuffer("\"");
buffer.append(MimeUtility.encodeText(name));
buffer.append("\" <").append(email);
buffer.append(">");
return buffer.toString();
}
/**
* 把文件转换成字节数组
* @param f 文件对象
* @return byte[] 字节数组
*/
private byte[] getBytesFromFile(File f) {
if (f == null) {
return null;
}
try {
InputStream stream = new FileInputStream(f);
ByteArrayOutputStream out = new ByteArrayOutputStream(1000);
byte[] b = new byte[1024];
int n;
while ((n = stream.read(b)) != -1) {
out.write(b, 0, n);
}
stream.close();
out.close();
return out.toByteArray();
} catch (IOException e){
e.printStackTrace();
}
return null;
}
/**
* 通过正则获取文件名
*/
private String getFileName(String filePath){
String regEx = "";
if(filePath.indexOf("\\") == -1){
regEx = ".+\\/(.+)$";
}
else{
regEx = ".+\\\\(.+)$";
}
Pattern p=Pattern.compile(regEx);
Matcher m=p.matcher(filePath);
String fileName = "";
if(m.find()){
fileName = m.group(1);
}
return fileName;
}
/**
* 内部类实现线程发送邮件
* @author Lanxiaowei
*
*/
private class SendEmailThread implements Runnable{
private MimeMessage message;
public SendEmailThread(MimeMessage message){
this.message = message;
}
public void run() {
try {
sendEmail();
} catch (MessagingException e) {
e.printStackTrace();
}
}
/**
* 发送邮件
* @return boolean 发送是否成功
* @throws MessagingException
*/
private boolean sendEmail() throws MessagingException{
Transport transport = null;
try {
URLName url = new URLName(
properties.getProperty("mail.transport.protocol"),
properties.getProperty("mail.host"),
Integer.parseInt(properties.getProperty("mail.port")),
"",
properties.getProperty("userName"),
properties.getProperty("passWord"));
transport = new SMTPTransport(session, url);
transport.connect(
properties.getProperty("mail.host"),
Integer.parseInt(properties.getProperty("mail.port")),
properties.getProperty("userName"),
properties.getProperty("passWord"));
transport.sendMessage(message, message.getRecipients(RecipientType.TO));
return true;
} finally {
if (transport != null) {
transport.close();
}
}
}
}
}
MailBean类是对邮件对象的自定义包装,代码如下:
package com.lxw.demo;
/**
* 邮件对象
* @author Lanxiaowei
* @createTime 2011-12-4 下午05:09:32
*/
public class MailBean {
/**
* 发件人邮箱地址
*/
private String fromMail;
/**
* 显示发件人姓名
*/
private String fromName;
/**
* 收件人邮箱地址
*/
private String[] toMail;
/**
* 显示收件人姓名
*/
private String[] toName;
/**
* 回复人邮箱地址
*/
private String[] replyEmail;
/**
* 回复人姓名
*/
private String[] replyName;
/**
* 抄送人邮箱地址
*/
private String[] ccMail;
/**
* 抄送人姓名
*/
private String[] ccName;
/**
* 密送人邮箱地址
*/
private String[] bccMail;
/**
* 密送人姓名
*/
private String[] bccName;
/**
* 邮件主题
*/
private String subject;
/**
* 邮件正文内容
*/
private String content;
/**
* 附件文件列表
*/
private String[] attchmentFileNames;
/**
* 正文部分插入图片列表
*/
private String[] picNames;
/**
* 邮件格式:纯文本格式、HTML格式
*/
private String mailFormat;
public String getFromMail() {
return fromMail;
}
public void setFromMail(String fromMail) {
this.fromMail = fromMail;
}
public String getFromName() {
return fromName;
}
public void setFromName(String fromName) {
this.fromName = fromName;
}
public String[] getToMail() {
return toMail;
}
public void setToMail(String[] toMail) {
this.toMail = toMail;
}
public String[] getToName() {
return toName;
}
public void setToName(String[] toName) {
this.toName = toName;
}
public String[] getReplyEmail() {
return replyEmail;
}
public void setReplyEmail(String[] replyEmail) {
this.replyEmail = replyEmail;
}
public String[] getReplyName() {
return replyName;
}
public void setReplyName(String[] replyName) {
this.replyName = replyName;
}
public String[] getCcMail() {
return ccMail;
}
public void setCcMail(String[] ccMail) {
this.ccMail = ccMail;
}
public String[] getCcName() {
return ccName;
}
public void setCcName(String[] ccName) {
this.ccName = ccName;
}
public String[] getBccMail() {
return bccMail;
}
public void setBccMail(String[] bccMail) {
this.bccMail = bccMail;
}
public String[] getBccName() {
return bccName;
}
public void setBccName(String[] bccName) {
this.bccName = bccName;
}
public String getSubject() {
return subject;
}
public void setSubject(String subject) {
this.subject = subject;
}
public String getContent() {
return content;
}
public void setContent(String content) {
this.content = content;
}
public String[] getAttchmentFileNames() {
return attchmentFileNames;
}
public void setAttchmentFileNames(String[] attchmentFileNames) {
this.attchmentFileNames = attchmentFileNames;
}
public String[] getPicNames() {
return picNames;
}
public void setPicNames(String[] picNames) {
this.picNames = picNames;
}
public String getMailFormat() {
return mailFormat;
}
public void setMailFormat(String mailFormat) {
this.mailFormat = mailFormat;
}
{
mailFormat = "html";
}
public MailBean(){}
/**
* 根据发件人email、收件人email、邮件主题、邮件正文构建邮件bean
*/
public MailBean(String fromMail, String[] toMail, String subject, String content) {
this(fromMail,"",toMail,null,null,null,null,null,null,null,subject,content,null,null,"");
}
/**
* 构建带附件的邮件bean
*/
public MailBean(String fromMail, String[] toMail, String subject, String content, String[] attchmentFileNames) {
this(fromMail,"",toMail,null,null,null,null,null,null,null,subject,content,attchmentFileNames,null,"");
}
/**
* 构建嵌入图片且带附件的邮件bean
*/
public MailBean(String fromMail, String[] toMail, String subject, String content, String[] attchmentFileNames, String[] picNames) {
this(fromMail,"",toMail,null,null,null,null,null,null,null,subject,content,attchmentFileNames,picNames,"");
}
/**
* 构建包含发件人、收件人、回复人、抄送人、密送人、主题、正文、图片、附件且email地址用中文友好显示的邮件bean
*/
public MailBean(String fromMail, String fromName, String[] toMail, String[] toName, String[] replyEmail, String[] replyName,
String[] ccMail, String[] ccName, String[] bccMail, String[] bccName, String subject, String content,
String[] attchmentFileNames, String[] picNames,String mailFormat) {
this.fromMail = fromMail;
this.fromName = fromName;
this.toMail = toMail;
this.toName = toName;
this.replyEmail = replyEmail;
this.replyName = replyName;
this.ccMail = ccMail;
this.ccName = ccName;
this.bccMail = bccMail;
this.bccName = bccName;
this.subject = subject;
this.content = content;
this.attchmentFileNames = attchmentFileNames;
this.picNames = picNames;
this.mailFormat = mailFormat;
}
}
mail.properties文件配置如下:
mail.smtp.host=smtp.sina.com
mail.host=smtp.sina.com
mail.smtp.auth=true
mail.transport.protocol=smtp
userName=vnetoolxw
passWord=beidaqn
charset=UTF-8
mail.port=25
#gmail特殊设置
mail.smtp.socketFactory.class=javax.net.ssl.SSLSocketFactory
mail.smtp.socketFactory.fallback=false
mail.smtp.socketFactory.port=25
写一天了,累,累,累啊!写完收工,洗洗睡觉咯!
本文来源 我爱IT技术网 http://www.52ij.com/jishu/91.html 转载请保留链接。
- 评论列表(网友评论仅供网友表达个人看法,并不表明本站同意其观点或证实其描述)
-
