利用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 = "邮件发送失败!错误原因:\n" + "身份验证错误!";
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;
}
}
}

  

Java实现多线程邮件发送的更多相关文章

  1. Spring进阶—如何用Java代码实现邮件发送(一)

    相关文章: <Spring进阶—如何用Java代码实现邮件发送(二)> 在一些项目里面如进销存系统,对一些库存不足发出预警提示消息,招聘网站注册用户验证email地址等都需要用到邮件发送技 ...

  2. java实现smtp邮件发送

    一.准备工作 首先你需要已一个发送邮箱,一般的邮箱都有SMTP.POP3服务,比如QQ邮箱,登陆QQ邮箱开启SMTP服务,开启是服务器会提示你设置独立密码,这个密码是跟邮箱正常登陆的密码不同的,这个是 ...

  3. Java实现QQ邮件发送客户端

    目录 一.前言:QQ邮件发送程序 二.封装SMTP操作 三.实现多线程接收 四.QQ邮件客户端界面设计 1.连接按钮 2.发送按钮 五.QQ邮件发送效果演示 六.总结 一.前言:QQ邮件发送程序 在上 ...

  4. java简单的邮件发送

    java实现简单的邮件发送案例,学会了这个你就可以利用这个来整你的好友了,不断地给他进行邮箱轰炸(当然个人不建议瞎搞),最重要的是明白其中的原理最好了.话不多说,直接看代码案例了.首先需要导入的jar ...

  5. Java实现QQ邮件发送

    首先我们需要两个jar包,点击下面即可下载这两个包: JavaMail mail.jar 1.4.5 JAF(版本 1.1.1) activation.jar 我们这里采用QQ邮箱发送邮件为例,代码如 ...

  6. java工具类-邮件发送

    mail-1.4.jar package com.huawei.it.citools.mail; import java.util.Date;import java.util.List;import ...

  7. Java 实现 HtmlEmail 邮件发送功能

    引言 在平常的企业级应用开发过程中,可能会涉及到一些资讯通知需要传达,以及软件使用过程中有一些安全性的东西需要及早知道和了解,这时候在局域网之间就可以通过发送邮件的方式了.以下就是代码实现了: pac ...

  8. Spring进阶—如何用Java代码实现邮件发送(二)

    http://www.cnblogs.com/itsource/p/4266905.html

  9. ASP.NET 邮件发送

    ASP.NET 邮件发送用NET的MAIL类即可实现. 邮件发时,为不影响进程,所以采用多线程实现比较好. /// <summary> /// 多线程邮件发送 多线程需注意不要引用到外部方 ...

随机推荐

  1. 土法炼钢:怎么实现一个简单的B+Tree In-Disk

    1. 写在前面 说起B+树,大家应该都很熟悉.B+树是一种平衡的多路搜索树,广泛在操作系统和数据库系统用作索引.相比于内存的存取速度,磁盘I/O存取的开销要高上几个数量级.而将B+树用作索引时,它可以 ...

  2. 用Ultra ISO制作启动U盘装系统

    用UltraISO制作启动U盘可以在没有光驱的情况下装系统. 现在有大容量U盘的越来越多,而且不装光驱的也越来越多. 那么用U盘装系统成为了可能和必须,不多废话了. 首先,需要准备的有: Ultra  ...

  3. Object-oriented features

    Python is an object-oriented programing language, which means that it provides features that support ...

  4. 洛谷P1465

    P1465 序言页码 Preface Numbering 74通过 111提交 题目提供者该用户不存在 标签USACO 难度普及/提高- 提交  讨论  题解 最新讨论 暂时没有讨论 题目描述 一类书 ...

  5. oracle:触发器,自治事务 trigger

    create or replace trigger TRI_FC83_INSERT before insert ON FC83 FOR EACH ROW declare PRAGMA AUTONOMO ...

  6. 重载(overload)、重写:覆盖(override)、重定义:遮蔽(redefine)、多态

    同一域名空间,函数名相同,签名不同 编译期绑定确定绑定函数,也称为静态多态 重写:覆盖(override) 虚函数 子类空间,函数名相同,签名相同 重定义:遮蔽(redefine) 非虚函数,子类成员 ...

  7. Oracle笔记 五、创建表、约束、视图、索引、序列、同义词、表空间

    alter table userInfo add(msn varchar2(20)); 1.建表 create table userInfo ( id number(6), name varchar2 ...

  8. nodejs安装及环境配置

    简单的说 Node.js 就是运行在服务端的 JavaScript. Node.js 是一个基于Chrome JavaScript 运行时建立的一个平台. Node.js是一个事件驱动I/O服务端Ja ...

  9. leetcode 121

    121. Best Time to Buy and Sell Stock Say you have an array for which the ith element is the price of ...

  10. Android IOS WebRTC 音视频开发总结(五三)-- 国内IM & RTC SDK列表

    本文主要总结国内提供RTC SDK的产品,转载必须说明出处,文章来自博客园RTC.Blacker,欢迎关注微信公众号blacker,更多详见www.rtc.help 自从开通邮件和微信公众号以来,很多 ...