Java实现多线程邮件发送

   利用java多线程技术配合线程池实现多任务邮件发送.

1.基本邮件发送MailSender

package hk.buttonwood.ops.email;

import java.io.File;
import java.util.Date;
import java.util.Enumeration;
import java.util.Properties;
import java.util.Vector;
import javax.activation.DataHandler;
import javax.activation.FileDataSource;
import javax.mail.Address;
import javax.mail.AuthenticationFailedException;
import javax.mail.BodyPart;
import javax.mail.Message;
import javax.mail.MessagingException;
import javax.mail.Multipart;
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 org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 * 简单邮件(带附件的邮件)发送器
 */
public class MailSender {
    private Logger logger = LoggerFactory.getLogger(MailSender.class);

    public static void main(String[] args) {
        // 这个类主要是设置邮件
        MailSenderInfo mailInfo = new MailSenderInfo();
        mailInfo.setMailServerHost("smtp.163.com");
        mailInfo.setMailServerPort("25");
        mailInfo.setValidate(true);
        mailInfo.setUserName("15138666597");
        mailInfo.setPassword("myb1991517");// 您的邮箱密码
        mailInfo.setFromAddress("15138666597@163.com");
        mailInfo.setToAddress("930147677@qq.com");
        mailInfo.setSubject("windowfg");
        mailInfo.setContent("asgjhkhl");
        // 这个类主要来发送邮件
        MailSender sms = new MailSender();
        Vector<File> files = new Vector<File>();
        files.addElement(new File("/home/maybo/myProject/2015-11-04/mt_2015-11-04_2.pdf"));
        mailInfo.setFile(files);
        sms.sendWithAttachment(mailInfo);// 发送文体格式
        // sms.sendHtmlMail(mailInfo);//发送html格式
    }

    /**
     * 发送邮件
     */
    public MailState sendWithAttachment(MailSenderInfo info) {
        MailState mailState=new MailState();
        mailState.setDate(info.getDate());
        mailState.setState(MailState.SUCCESS);
        mailState.setDesc("邮箱发送成功!");
        mailState.setAddress(info.getToAddress());
        Session session = null;
        Properties props = System.getProperties();
        props.put("mail.smtp.host", info.getMailServerHost());
        if (info.isValidate()) { // 服务器需要身份认证
            props.put("mail.smtp.auth", "true");
            MyAuthenticator smtpAuth = new MyAuthenticator(info.getUserName(), info.getPassword());
            session = Session.getDefaultInstance(props, smtpAuth);
        } else {
            props.put("mail.smtp.auth", "false");
            session = Session.getDefaultInstance(props, null);
        }
        //session.setDebug(true);
        Transport trans = null;
        try {
            Message msg = new MimeMessage(session);
            try {
                Address from_address = new InternetAddress(info.getFromAddress(), info.getUserName());
                msg.setFrom(from_address);
            } catch (java.io.UnsupportedEncodingException e) {
                //e.printStackTrace();
                mailState.setState(MailState.ERROR);
                String message = "邮件发送失败!";
                mailState.setDesc(message);
            }
            InternetAddress[] address = { new InternetAddress(info.getToAddress()) };
            msg.setRecipients(Message.RecipientType.TO, address);
            msg.setSubject(info.getSubject());
            Multipart mp = new MimeMultipart();
            MimeBodyPart mbp = new MimeBodyPart();
            mbp.setContent(info.getContent().toString(), "text/html;charset=gb2312");
            mp.addBodyPart(mbp);
            if (!info.getFile().isEmpty()) {// 有附件
                Enumeration<?> efile = info.getFile().elements();
                while (efile.hasMoreElements()) {
                    mbp = new MimeBodyPart();
                    String filename = efile.nextElement().toString(); // 选择出每一个附件名
                    FileDataSource fds = new FileDataSource(filename); // 得到数据源
                    mbp.setDataHandler(new DataHandler(fds)); // 得到附件本身并至入BodyPart
                    mbp.setFileName(fds.getName()); // 得到文件名同样至入BodyPart
                    mp.addBodyPart(mbp);
                }
                info.getFile().removeAllElements();
            }
            msg.setContent(mp); // Multipart加入到信件
            msg.setSentDate(new Date()); // 设置信件头的发送日期
            // 发送信件
            msg.saveChanges();
            trans = session.getTransport("smtp");
            trans.connect(info.getMailServerHost(), info.getUserName(), info.getPassword());
            trans.sendMessage(msg, msg.getAllRecipients());
            trans.close();

        } catch (AuthenticationFailedException e) {
            mailState.setState(MailState.ERROR);
            String message = "邮件发送失败!错误原因:
" + "身份验证错误!";
            mailState.setDesc(message);
        //    e.printStackTrace();
        } catch (MessagingException e) {
            //e.printStackTrace();
            String message = "邮件发送失败!错误原因:" + e.getMessage();
            mailState.setDesc(message);
            mailState.setState(MailState.ERROR);
        }
        return mailState;
    }

    /**
     * 以文本格式发送邮件
     * 
     * @param mailInfo
     *            待发送的邮件的信息
     */
    public boolean sendTextMail(MailSenderInfo mailInfo) {
        // 判断是否需要身份认证
        MyAuthenticator authenticator = null;
        Properties pro = mailInfo.getProperties();
        if (mailInfo.isValidate()) {
            // 如果需要身份认证,则创建一个密码验证器
            authenticator = new MyAuthenticator(mailInfo.getUserName(), mailInfo.getPassword());
        }
        // 根据邮件会话属性和密码验证器构造一个发送邮件的session
        Session sendMailSession = Session.getDefaultInstance(pro, authenticator);
        try {
            // 根据session创建一个邮件消息
            Message mailMessage = new MimeMessage(sendMailSession);
            // 创建邮件发送者地址
            Address from = new InternetAddress(mailInfo.getFromAddress());
            // 设置邮件消息的发送者
            mailMessage.setFrom(from);
            // 创建邮件的接收者地址,并设置到邮件消息中
            Address to = new InternetAddress(mailInfo.getToAddress());
            mailMessage.setRecipient(Message.RecipientType.TO, to);
            // 设置邮件消息的主题
            mailMessage.setSubject(mailInfo.getSubject());
            // 设置邮件消息发送的时间
            mailMessage.setSentDate(new Date());
            // 设置邮件消息的主要内容
            String mailContent = mailInfo.getContent();
            mailMessage.setText(mailContent);
            // 发送邮件
            Transport.send(mailMessage);
            return true;
        } catch (MessagingException ex) {
            ex.printStackTrace();
        }
        return false;
    }

    /**
     * 以HTML格式发送邮件
     * 
     * @param mailInfo
     *            待发送的邮件信息
     */
    public static boolean sendHtmlMail(MailSenderInfo mailInfo) {
        // 判断是否需要身份认证
        MyAuthenticator authenticator = null;
        Properties pro = mailInfo.getProperties();
        // 如果需要身份认证,则创建一个密码验证器
        if (mailInfo.isValidate()) {
            authenticator = new MyAuthenticator(mailInfo.getUserName(), mailInfo.getPassword());
        }
        // 根据邮件会话属性和密码验证器构造一个发送邮件的session
        Session sendMailSession = Session.getDefaultInstance(pro, authenticator);
        try {
            // 根据session创建一个邮件消息
            Message mailMessage = new MimeMessage(sendMailSession);
            // 创建邮件发送者地址
            Address from = new InternetAddress(mailInfo.getFromAddress());
            // 设置邮件消息的发送者
            mailMessage.setFrom(from);
            // 创建邮件的接收者地址,并设置到邮件消息中
            Address to = new InternetAddress(mailInfo.getToAddress());
            // Message.RecipientType.TO属性表示接收者的类型为TO
            mailMessage.setRecipient(Message.RecipientType.TO, to);
            // 设置邮件消息的主题
            mailMessage.setSubject(mailInfo.getSubject());
            // 设置邮件消息发送的时间
            mailMessage.setSentDate(new Date());
            // MiniMultipart类是一个容器类,包含MimeBodyPart类型的对象
            Multipart mainPart = new MimeMultipart();
            // 创建一个包含HTML内容的MimeBodyPart
            BodyPart html = new MimeBodyPart();
            // 设置HTML内容
            html.setContent(mailInfo.getContent(), "text/html; charset=utf-8");
            mainPart.addBodyPart(html);
            // 将MiniMultipart对象设置为邮件内容
            mailMessage.setContent(mainPart);
            // 发送邮件
            Transport.send(mailMessage);
            return true;
        } catch (MessagingException ex) {
            ex.printStackTrace();
        }
        return false;
    }
}

2.邮件发送信息MailSenderInfo

package hk.buttonwood.ops.email;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.Serializable;
import java.util.Arrays;
import java.util.Properties;
import java.util.Vector;
public class MailSenderInfo implements Serializable  {
	 // 发送邮件的服务器的IP和端口   
    private String mailServerHost;   
    private String mailServerPort = "25";  
    private long uid;//唯一标示
    // 邮件发送者的地址   
    private String fromAddress;   
    // 邮件接收者的地址   
    private String toAddress;   
    // 登陆邮件发送服务器的用户名和密码   
    private String userName;   
    private String password;   
    // 是否需要身份验证   
    private boolean validate = false;   
    // 邮件主题   
    private String filename="";  
    private Vector file = new Vector(); //用于保存发送附件的文件名的集合  
    private String subject;   
    // 邮件的文本内容   
    private String content;   
    // 邮件附件的文件名   
    private String[] attachFileNames;    
    //邮箱来源
    private int portfolio;
    //邮箱来源日期
    private String date;
    public void setUid(long uid) {
		this.uid = uid;
	}
    public long getUid() {
		return uid;
	}
    public void setDate(String date) {
		this.date = date;
	}
    public void setPortfolio(int portfolio) {
		this.portfolio = portfolio;
	}
    public String getDate() {
		return this.date;
	}
    public int getPortfolio() {
		return this.portfolio;
	}
    /**  
      * 获得邮件会话属性  
      */   
    public Properties getProperties(){   
      Properties p = new Properties();   
      p.put("mail.smtp.host", this.mailServerHost);   
      p.put("mail.smtp.port", this.mailServerPort);   
      p.put("mail.smtp.auth", validate ? "true" : "false");   
      return p;   
    }   
    public String getMailServerHost() {   
      return mailServerHost;   
    }   
    public void setFile(Vector file) {
		this.file = file;
	}
    public Vector getFile() {
		return this.file;
	}
    public void setFilename(String filename) {
		this.filename = filename;
	}
    public String getFilename() {
		return this.filename;
	}
    public void setMailServerHost(String mailServerHost) {   
      this.mailServerHost = mailServerHost;   
    }  
    public String getMailServerPort() {   
      return mailServerPort;   
    }  
    public void setMailServerPort(String mailServerPort) {   
      this.mailServerPort = mailServerPort;   
    }  
    public boolean isValidate() {   
      return validate;   
    }  
    public void setValidate(boolean validate) {   
      this.validate = validate;   
    }  
    public String[] getAttachFileNames() {   
      return attachFileNames;   
    }  
    public void setAttachFileNames(String[] fileNames) {   
      this.attachFileNames = fileNames;   
    }  
    public String getFromAddress() {   
      return fromAddress;   
    }   
    public void setFromAddress(String fromAddress) {   
      this.fromAddress = fromAddress;   
    }  
    public String getPassword() {   
      return password;   
    }  
    public void setPassword(String password) {   
      this.password = password;   
    }  
    public String getToAddress() {   
      return toAddress;   
    }   
    public void setToAddress(String toAddress) {   
      this.toAddress = toAddress;   
    }   
    public String getUserName() {   
      return userName;   
    }  
    public void setUserName(String userName) {   
      this.userName = userName;   
    }  
    public String getSubject() {   
      return subject;   
    }  
    public void setSubject(String subject) {   
      this.subject = subject;   
    }  
    public String getContent() {   
      return content;   
    }  
    public void setContent(String textContent) {   
      this.content = textContent;   
    }
    public Object deepCopy() throws Exception  
    {  
        // 将该对象序列化成流,因为写在流里的是对象的一个拷贝,而原对象仍然存在于JVM里面。所以利用这个特性可以实现对象的深拷贝  
        ByteArrayOutputStream bos = new ByteArrayOutputStream();  
  
        ObjectOutputStream oos = new ObjectOutputStream(bos);  
  
        oos.writeObject(this);  
  
        // 将流序列化成对象  
        ByteArrayInputStream bis = new ByteArrayInputStream(bos.toByteArray());  
  
        ObjectInputStream ois = new ObjectInputStream(bis);  
  
        return ois.readObject();  

}
	@Override
	public String toString() {
		return "MailSenderInfo [mailServerHost=" + this.mailServerHost + ", mailServerPort=" + this.mailServerPort
				+ ", fromAddress=" + this.fromAddress + ", toAddress=" + this.toAddress + ", userName=" + this.userName
				+ ", password=" + this.password + ", validate=" + this.validate + ", filename=" + this.filename
				+ ", file=" + this.file + ", subject=" + this.subject + ", content=" + this.content
				+ ", attachFileNames=" + Arrays.toString(this.attachFileNames) + ", portfolio=" + this.portfolio
				+ ", date=" + this.date + "]";
	}  
	
    
}

3.权限MyAuthenticator

package hk.buttonwood.ops.email;

import javax.mail.Authenticator;
import javax.mail.PasswordAuthentication;

public class MyAuthenticator extends Authenticator {
	String userName = null;
	String password = null;

	public MyAuthenticator() {
	}

	public MyAuthenticator(String username, String password) {
		this.userName = username;
		this.password = password;
	}

	protected PasswordAuthentication getPasswordAuthentication() {
		return new PasswordAuthentication(userName, password);
	}
}

4.创建一个发送邮件的线程任务

package hk.buttonwood.ops.email;
import java.util.concurrent.LinkedBlockingQueue;
import hk.buttonwood.ops.email.MailState;

/**
 * @author maybo 2015年11月4日
 */
public class MailSendTask extends Thread {
	private LinkedBlockingQueue<MailState> msgs;// 非阻塞线程安全队列用于存储发送的消息

	public void setMsgs(LinkedBlockingQueue<MailState> msgs) {
		this.msgs = msgs;
	}

	private MailSenderInfo mailSenderInfo;

	public void setMailSenderInfo(MailSenderInfo mailSenderInfo) {
		this.mailSenderInfo = mailSenderInfo;
	}

	/*
	 * @param:发送的消息状态
	 * 
	 * @param:发送信息
	 */
	public MailSendTask(LinkedBlockingQueue<MailState> msgs, MailSenderInfo mailSenderInfo) {
		this.msgs = msgs;
		this.mailSenderInfo = mailSenderInfo;
	}

	@Override
	public void run() {
		MailSender mailSender = new MailSender();
		MailState mailState = mailSender.sendWithAttachment(mailSenderInfo);
		msgs.add(mailState);
	}
}

  5.邮件发送服务

package hk.buttonwood.ops.email;

import java.io.File;
import java.util.List;
import java.util.Vector;
import java.util.concurrent.LinkedBlockingQueue;
import javax.annotation.Resource;
import hk.buttonwood.ops.report.BaseReportConf;
import net.zweb.core.util.FileUtil;

/**
 * @author maybo 2015年11月4日
 */

@Resource
public class MailSendService extends BaseReportConf {
	public LinkedBlockingQueue<MailState> msgs;
	public MailSenderOperation mailSenderOperation;

	private  ReportSendInfo info = null;

	public MailSendService() {
		mailSenderOperation = new MailSenderOperation();
		msgs = new LinkedBlockingQueue<MailState>();
		mailSenderOperation.excute(msgs);
		info = ReportSendInfo.instance();
	}

	public void send(List<String> toAddress, String reportType, String date,String date2, int portfolio, String root, long uid)
			throws Exception {
		MailState mailState = new MailState();
		mailState.setPorftolio(portfolio);
		mailState.setUid(uid);
		if (toAddress == null) {
			mailState.setDate(date);
			mailState.setDate(date);
			mailState.setState(MailState.NOT_ADDRESS);
			mailState.setDesc("没有相应发送地址!");
			msgs.add(mailState);
			return;
		}
		File file = obtainFile(date,date2, reportType, portfolio, root);
		if (file != null) {
			MailSenderInfo mInfo = info.create(reportType);
			Vector<File> vectors = new Vector<File>();
			vectors.addElement(file);
			mInfo.setFile(vectors);
			for (int i = 0; i < toAddress.size(); i++) {
				MailSenderInfo senderInfo = new MailSenderInfo();
				senderInfo = cpSendInfo(mInfo);
				senderInfo.setToAddress(toAddress.get(i));
				senderInfo.setPortfolio(portfolio);
				senderInfo.setDate(date);
				senderInfo.setUid(uid);
				mailSenderOperation.addTask(senderInfo);
			}
		} else {
			mailState.setPorftolio(portfolio);
			mailState.setUid(uid);
			mailState.setDate(date);
			mailState.setState(MailState.NOT_EXIST);
			mailState.setDesc("发送的报表没有生成!");
			msgs.add(mailState);
		}
	}

	private MailSenderInfo cpSendInfo(MailSenderInfo info) {
		MailSenderInfo senderInfo = new MailSenderInfo();
		senderInfo.setAttachFileNames(info.getAttachFileNames());
		senderInfo.setContent(info.getContent());
		senderInfo.setFile(info.getFile());
		senderInfo.setFilename(info.getFilename());
		senderInfo.setFromAddress(info.getFromAddress());
		senderInfo.setMailServerHost(info.getMailServerHost());
		senderInfo.setMailServerPort(info.getMailServerPort());
		senderInfo.setPassword(info.getPassword());
		senderInfo.setSubject(info.getSubject());
		senderInfo.setToAddress(info.getToAddress());
		senderInfo.setUserName(info.getUserName());
		senderInfo.setValidate(info.isValidate());
		return senderInfo;
	}

	/*
	 * 通过日期,报告类型,以及投资组合获取对应的pdf
	 */
	private File obtainFile(String date,String date2, String reportType, int portfolio, String root) {
		String path = null;
		if(date2==null||date2==""){
		 path = root + "/" + reportType + "_" + date + "_" + portfolio + ".pdf";
		}else{
			 path = root + "/" + reportType + "_" + date+"_"+date2 + "_" + portfolio + ".pdf";
		}
		if (!FileUtil.exists(path)) {
			return null;
		} else {
			File file = new File(path);
			return file;
		}
	}
}

  

原文地址:https://www.cnblogs.com/maybo/p/5182513.html