- 浏览: 141692 次
- 性别:
- 来自: 合肥
文章分类
最新评论
-
tjg138:
many thanks!!!!!
Hibernate QBC查询 -
tjg138:
Criteria criteria=session.creat ...
Hibernate QBC查询 -
wa114d:
能不能把你源码放上啊,谢谢啊
Javamail -
cfyme:
重构过的代码 我去运行 怎么也执行不到EmailRunner中 ...
Javamail -
cfyme:
大师,你有没有源文件 你上传附件不是正确的
Javamail
Javamail,论坛上由已经有很多的讨论,但是俺觉得还是不够完整,不完整不是说讲的不细致,而是指不全面,而是缺少high level的全面论述,所以俺来补充一下。
这篇文章的名字起得很古怪(估计还有人暗地里说文章名字取得如何如何,文章实质却是水货等等了,先不忙下结论,各位看官接着往下看便知),叫简单和复杂之间,为什么要取这么个奇怪的名字,搞得人一头雾水,其实我想要表达的意思是这样的,之前坛子上有很多人讨论过如何使用javamail(包括spring对其的封装),也有人讨论过如何通过jms发送emal,一个是简单的api介绍,一个是比较复杂的异步方案,但是试问除了简单使用其api难道就只能使用jms来进行异步发送了吗,我们可以再找到一种介于这两者之间的方案,就是concurrent(我的建议是在普通的web应用中邮件发送不需要用jms,但是最好也不要使用同步发送,所以普通的web应该使用concurrent来进行异步邮件发送应该是比较好的选择)。
在普通的web应用中,发送邮件应该只能算小任务,而使用jms来发送邮件有点杀鸡用牛刀的味道,那么如果能建立一个线程池来管理这些小线程并重复使用他们,应该来说是一个简单有效的方案,我们可以使用concurrent包中的Executors来建立线程池,Executors是一个工厂,也是一个工具类,我把它的api的介绍简单的翻译了一下(如果翻译有误请大家不要吝啬手中的砖头)
方 法 说 明
newCachedThreadPool() 创建一个包含新线程的线程池,池中线程的数量需要预先指定,该线程池会复用之前创建的线程(前提是该线程还是有效线程)。如果你的要执行的任务是短生命周期的任务的话,使用这种池提高性能是很具代表性的。这个方法有一个重载
newFixedThreadPool() 创建一个线程池以复用指定数量的线程,如果当所有线程都是活动状态时(指这些线程都在运行),那么新的任务将会等待,知道有空余的线程。如果有任何一个线程因为在运行中发生错误而终结(非正常shutdown),那么如果有新的任务要并发处理,concurrent就会创建一个新的线程放入池中。
newSingleThreadExecutor() 创建一个使用单工作线程的executor,
newScheduledThreadPool() 可调度的线程池,池中的线程可以在某一时间延迟之后执行,也可以周期性执行
newSingleThreadScheduledExecutor() 单一可调度的线程
上面我重点解释了newFixedThreadPool(),因为我们将使用newFixedThreadPool方法来创建一个线程池,这个线程池中存放的线程就是我们用来发送邮件的。代码如下:
Java代码
/**
* 由spring管理的线程池类,返回的ExecutorService就是给我们来执行线程的
*如果不交给spring管理也是可以的,可以使用单例模式来实现同样功能,但是poolSize *要hardcode了
* @author 张荣华(ahuaxuan)
* @version $Id$
*/
public class EasyMailExecutorPool implements InitializingBean {
//线程池大小,spring配置文件中配置
private int poolSize;
private ExecutorService service;
public ExecutorService getService() {
return service;
}
public int getPoolSize() {
return poolSize;
}
public void setPoolSize(int poolSize) {
this.poolSize = poolSize;
}
/**
* 在 bean 被初始化成功之后初始化线程池大小
*/
public void afterPropertiesSet() throws Exception {
service = Executors.newFixedThreadPool(poolSize);
}
}
/**
* 由spring管理的线程池类,返回的ExecutorService就是给我们来执行线程的
*如果不交给spring管理也是可以的,可以使用单例模式来实现同样功能,但是poolSize *要hardcode了
* @author 张荣华(ahuaxuan)
* @version $Id$
*/
public class EasyMailExecutorPool implements InitializingBean {
//线程池大小,spring配置文件中配置
private int poolSize;
private ExecutorService service;
public ExecutorService getService() {
return service;
}
public int getPoolSize() {
return poolSize;
}
public void setPoolSize(int poolSize) {
this.poolSize = poolSize;
}
/**
* 在 bean 被初始化成功之后初始化线程池大小
*/
public void afterPropertiesSet() throws Exception {
service = Executors.newFixedThreadPool(poolSize);
}
}
这样我们就初始化了线程池的大小,接下来就是如何使用这个线程池中的线程了,我们看看MailService是如何来使用线程池中的线程的,这个类中的代码我已经作了详细的解释
Java代码
/**
* 用来发送 mail 的 service, 其中有一个内部类专门用来供线程使用
* @author 张荣华(ahuaxuan)
* @since 2007-7-11
* @version $Id$
*/
public class EasyMailServieImpl implements EasyMailService{
private static transient Log logger = LogFactory.getLog(EasyMailServieImpl.class);
//注入MailSender
private JavaMailSender javaMailSender;
//注入线程池
private EasyMailExecutorPool easyMailExecutorPool;
//设置发件人
private String from;
public void setEasyMailExecutorPool(EasyMailExecutorPool easyMailExecutorPool) {
this.easyMailExecutorPool = easyMailExecutorPool;
}
public void setJavaMailSender(JavaMailSender javaMailSender) {
this.javaMailSender = javaMailSender;
}
public void setFrom(String from) {
this.from = from;
}
/**
* 简单的邮件发送接口,感兴趣的同学可以在这个基础上继续添加
* @param to
* @param subject
* @param text
*/
public void sendMessage(EmailEntity email){
if (null == email) {
if (logger.isDebugEnabled()) {
logger.debug("something you need to tell here");
}
return;
}
SimpleMailMessage simpleMailMessage = new SimpleMailMessage();
simpleMailMessage.setTo(email.getTo());
simpleMailMessage.setSubject(email.getSubject());
simpleMailMessage.setText(email.getText());
simpleMailMessage.setFrom(from);
easyMailExecutorPool.getService().execute(new MailRunner(simpleMailMessage));
}
/**
* 发送复杂格式邮件的接口,可以添加附件,图片,等等,但是需要修改这个方法,
* 如何做到添加附件和图片论坛上有例子了,需要的同学搜一下,
* 事实上这里的text参数最好是来自于模板,用模板生成html页面,然后交给javamail去发送,
* 如何使用模板来生成html见 {@link http://www.iteye.com/topic/71430 }
*
* @param to
* @param subject
* @param text
* @throws MessagingException
*/
public void sendMimeMessage(EmailEntity email) throws MessagingException {
if (null == email) {
if (logger.isDebugEnabled()) {
logger.debug("something you need to tell here");
}
return;
}
MimeMessage message = javaMailSender.createMimeMessage();
MimeMessageHelper helper = new MimeMessageHelper(message);
helper.setTo(email.getTo());
helper.setFrom(from);
helper.setSubject(email.getSubject());
this.addAttachmentOrImg(helper, email.getAttachment(), true);
this.addAttachmentOrImg(helper, email.getImg(), false);
//这里的text是html格式的, 可以使用模板引擎来生成html模板, velocity或者freemarker都可以做到
helper.setText(email.getText(),true);
easyMailExecutorPool.getService().execute(new MailRunner(message));
}
/**
* 添加附件或者是图片
* @param helper
* @param map
* @param isAttachment
* @throws MessagingException
*/
private void addAttachmentOrImg(MimeMessageHelper helper, Map map, boolean isAttachment) throws MessagingException {
for (Iterator it = map.entrySet().iterator(); it.hasNext();) {
Map.Entry entry = (Map.Entry) it.next();
String key = (String) entry.getKey();
String value = (String) entry.getValue();
if (StringUtils.isNotBlank(key) && StringUtils.isNotBlank(value)) {
FileSystemResource file = new FileSystemResource(new File(value));
if (!file.exists()) continue;
if (isAttachment) {
helper.addAttachment(key, file);
} else {
helper.addInline(key, file);
}
}
}
}
/**
* 用来发送邮件的 Runnable, 该类是一个内部类,之所以使用内部类,而没有使用嵌套类(静态内部类),
* 是因为内部类可以之间得到 service 的 javaMailSender
* 每次发送邮件都会从线程池中取一个线程, 然后进行发邮件操作
* @author ahuaxuan
*/
private class MailRunner implements Runnable {
SimpleMailMessage simpleMailMessage;
MimeMessage mimeMessage;
/**
* 构造简单文本邮件
* @param simpleMailMessage
*/
public MailRunner(SimpleMailMessage simpleMailMessage) {
if (mimeMessage == null) {
this.simpleMailMessage = simpleMailMessage;
}
}
/**
* 构造复杂邮件,可以添加附近,图片,等等
* @param mimeMessage
*/
public MailRunner(MimeMessage mimeMessage) {
if (simpleMailMessage == null) {
this.mimeMessage = mimeMessage;
}
}
/**
* 该方法将在线程池中的线程中执行
*/
public void run() {
try {
if (simpleMailMessage != null) {
javaMailSender.send(this.simpleMailMessage);
} else if (mimeMessage != null) {
javaMailSender.send(this.mimeMessage);
}
} catch (Exception e) {
if (logger.isDebugEnabled()) {
logger.debug("logger something here", e);
}
}
}
}
}
/**
* 用来发送 mail 的 service, 其中有一个内部类专门用来供线程使用
* @author 张荣华(ahuaxuan)
* @since 2007-7-11
* @version $Id$
*/
public class EasyMailServieImpl implements EasyMailService{
private static transient Log logger = LogFactory.getLog(EasyMailServieImpl.class);
//注入MailSender
private JavaMailSender javaMailSender;
//注入线程池
private EasyMailExecutorPool easyMailExecutorPool;
//设置发件人
private String from;
public void setEasyMailExecutorPool(EasyMailExecutorPool easyMailExecutorPool) {
this.easyMailExecutorPool = easyMailExecutorPool;
}
public void setJavaMailSender(JavaMailSender javaMailSender) {
this.javaMailSender = javaMailSender;
}
public void setFrom(String from) {
this.from = from;
}
/**
* 简单的邮件发送接口,感兴趣的同学可以在这个基础上继续添加
* @param to
* @param subject
* @param text
*/
public void sendMessage(EmailEntity email){
if (null == email) {
if (logger.isDebugEnabled()) {
logger.debug("something you need to tell here");
}
return;
}
SimpleMailMessage simpleMailMessage = new SimpleMailMessage();
simpleMailMessage.setTo(email.getTo());
simpleMailMessage.setSubject(email.getSubject());
simpleMailMessage.setText(email.getText());
simpleMailMessage.setFrom(from);
easyMailExecutorPool.getService().execute(new MailRunner(simpleMailMessage));
}
/**
* 发送复杂格式邮件的接口,可以添加附件,图片,等等,但是需要修改这个方法,
* 如何做到添加附件和图片论坛上有例子了,需要的同学搜一下,
* 事实上这里的text参数最好是来自于模板,用模板生成html页面,然后交给javamail去发送,
* 如何使用模板来生成html见 {@link http://www.iteye.com/topic/71430 }
*
* @param to
* @param subject
* @param text
* @throws MessagingException
*/
public void sendMimeMessage(EmailEntity email) throws MessagingException {
if (null == email) {
if (logger.isDebugEnabled()) {
logger.debug("something you need to tell here");
}
return;
}
MimeMessage message = javaMailSender.createMimeMessage();
MimeMessageHelper helper = new MimeMessageHelper(message);
helper.setTo(email.getTo());
helper.setFrom(from);
helper.setSubject(email.getSubject());
this.addAttachmentOrImg(helper, email.getAttachment(), true);
this.addAttachmentOrImg(helper, email.getImg(), false);
//这里的text是html格式的, 可以使用模板引擎来生成html模板, velocity或者freemarker都可以做到
helper.setText(email.getText(),true);
easyMailExecutorPool.getService().execute(new MailRunner(message));
}
/**
* 添加附件或者是图片
* @param helper
* @param map
* @param isAttachment
* @throws MessagingException
*/
private void addAttachmentOrImg(MimeMessageHelper helper, Map map, boolean isAttachment) throws MessagingException {
for (Iterator it = map.entrySet().iterator(); it.hasNext();) {
Map.Entry entry = (Map.Entry) it.next();
String key = (String) entry.getKey();
String value = (String) entry.getValue();
if (StringUtils.isNotBlank(key) && StringUtils.isNotBlank(value)) {
FileSystemResource file = new FileSystemResource(new File(value));
if (!file.exists()) continue;
if (isAttachment) {
helper.addAttachment(key, file);
} else {
helper.addInline(key, file);
}
}
}
}
/**
* 用来发送邮件的 Runnable, 该类是一个内部类,之所以使用内部类,而没有使用嵌套类(静态内部类),
* 是因为内部类可以之间得到 service 的 javaMailSender
* 每次发送邮件都会从线程池中取一个线程, 然后进行发邮件操作
* @author ahuaxuan
*/
private class MailRunner implements Runnable {
SimpleMailMessage simpleMailMessage;
MimeMessage mimeMessage;
/**
* 构造简单文本邮件
* @param simpleMailMessage
*/
public MailRunner(SimpleMailMessage simpleMailMessage) {
if (mimeMessage == null) {
this.simpleMailMessage = simpleMailMessage;
}
}
/**
* 构造复杂邮件,可以添加附近,图片,等等
* @param mimeMessage
*/
public MailRunner(MimeMessage mimeMessage) {
if (simpleMailMessage == null) {
this.mimeMessage = mimeMessage;
}
}
/**
* 该方法将在线程池中的线程中执行
*/
public void run() {
try {
if (simpleMailMessage != null) {
javaMailSender.send(this.simpleMailMessage);
} else if (mimeMessage != null) {
javaMailSender.send(this.mimeMessage);
}
} catch (Exception e) {
if (logger.isDebugEnabled()) {
logger.debug("logger something here", e);
}
}
}
}
}
MailService中的EmailEntity是对邮件的抽象(我只使用了失血模型,事实上我们也可以让这个EmailEntity来实现Runnable接口,这样Service中的内部类就可以去掉了,同时service中的大部分代码就要搬到EmailEntity及其父类里了,大家更倾向于怎么做呢?),代码如下:
Java代码
/**
* 该类是对邮件的抽象,邮件有哪些属性,这个类就有哪些属性 显然这个只是一个例子,
* 这个例子中附带mimemessage发送所需的附件或者图片(如果有的话)
* 需要使用的同学自己扩展
*
* @author 张荣华(ahuaxuan)
* @version $Id$
*/
public class EmailEntity {
String to;
String subject;
String text;
//邮件附件
Map<String, String> attachment = new HashMap<String, String>();
//邮件图片
Map<String, String> img = new HashMap<String, String>();
//这里省去大段的getter和setter方法
}
/**
* 该类是对邮件的抽象,邮件有哪些属性,这个类就有哪些属性 显然这个只是一个例子,
* 这个例子中附带mimemessage发送所需的附件或者图片(如果有的话)
* 需要使用的同学自己扩展
*
* @author 张荣华(ahuaxuan)
* @version $Id$
*/
public class EmailEntity {
String to;
String subject;
String text;
//邮件附件
Map<String, String> attachment = new HashMap<String, String>();
//邮件图片
Map<String, String> img = new HashMap<String, String>();
//这里省去大段的getter和setter方法
}
接下来就是在spring的配置文件中配置这些类了,我相信对熟悉spring的人来说这不是什么大问题:
Java代码
<beans>
<bean id="javaMailSender" class="org.springframework.mail.javamail.JavaMailSenderImpl" autowire="byName">
<property name="host" value="${mail.host}"/>
<property name="username" value="${mail.username}"/>
<property name="password" value="${mail.password}"/>
</bean>
<bean id="easyMailExecutorPool" class="org.zhangronghua.easymail.EasyMailExecutorPool" autowire="byName">
<property name="poolSize">
<value>5</value>
</property>
</bean>
<bean id="easyMailService" class="org.zhangronghua.easymail.EasyMailServieImpl" autowire="byName">
<property name="from" value="${mail.default.from}"/>
</bean>
</beans>
<beans>
<bean id="javaMailSender" class="org.springframework.mail.javamail.JavaMailSenderImpl" autowire="byName">
<property name="host" value="${mail.host}"/>
<property name="username" value="${mail.username}"/>
<property name="password" value="${mail.password}"/>
</bean>
<bean id="easyMailExecutorPool" class="org.zhangronghua.easymail.EasyMailExecutorPool" autowire="byName">
<property name="poolSize">
<value>5</value>
</property>
</bean>
<bean id="easyMailService" class="org.zhangronghua.easymail.EasyMailServieImpl" autowire="byName">
<property name="from" value="${mail.default.from}"/>
</bean>
</beans>
经过这么一番折腾之后,一个邮件发送的雏形就完成了,接着需要什么样的邮件发送功能就可以随意往MailService里添加内容了, 而如果需要用模板来生成html格式的邮件真的需要看http://www.iteye.com/topic/71430这个贴了,无论你是想用velocity还是想用freemarker来做模板引擎,这个贴中的例子都是可以直接拿来使用的
总结,如果自己起线程来发送邮件是一个非常危险的事情,如果并发一高(比如超过20),服务器估计就快撑不住了,而如果使用jms来异步发送邮件,学习的曲线高,成本也高,我不建议为了一个小小的邮件发送就在项目中导入jms(之所以这样说是因为还有很多项目就是基于webservice的,那么使用jms来调度webservice是一个不错的选择),所以使用线程池来实现这个异步的功能既安全又简单,这个例子是开源的,大家可以在自己的项目中随意修改,随意封装。
要注意的是,concurrent在jdk5.0以上版本中才有,如果你使用的是1.4的jdk需要单独下载concurrent包。
作者:张荣华,未经作者同意不得随意转载!
声明:JavaEye文章版权属于作者,受法律保护。没有作者书面许可不得转载。
推荐链接: 参加微软MSN机器人大赛,挑战你的想象力!赢取HP笔记本大奖!
推荐链接: qinysong :基于开源工作流引擎OSWorkflow的业务系统实例——请假审批系统您每点击一次,微软即为慈善事业捐出一分钱!
返回顶楼
ahuaxuan
等级:
性别:
文章: 549
积分: 1296
来自: 上海
时间:2007-07-12 收藏 收入博客 昨天发的帖子说错了一个概念:上面例子中其实使用的是失血模型,我说成了贫血模型,在此更正一下,经过思考,我觉得对这个邮件的抽象用真正的贫血模型是比较合适的,也比失血模型更加的oo,而且代码我也已经重构过了,重构完之后发现最后的结果是整个就是一strategy+adapter,最后service中的方法变成了这个德行(service中的方法变成了策略的调用者)
Java代码
public void sendMimeMessage(EmailEntity email) throws MessagingException {
email.setFrom(from);
email.generateMimeMailMessage(javaMailSender, easyMailExecutorPool.getService());
email.send();
}
public void sendMimeMessage(EmailEntity email) throws MessagingException {
email.setFrom(from);
email.generateMimeMailMessage(javaMailSender, easyMailExecutorPool.getService());
email.send();
}
方法都跑EmailEntity和其父类中去了,但是我没有办法在Entity中注入需要的service,只要作为参数传了进去,从整体上来看,整个easymail变得更加得面向对象了。这让我体会到贫血模型确实要比失血模型更oo
我们看看EmailEntity中得代码:
Java代码
/**
* 该类是对邮件的抽象,邮件有哪些属性,这个类就有哪些属性 显然这个只是一个例子,
* 这个例子中附带mimemessage发送所需的附件或者图片(如果有的话)
* 需要使用的同学自己扩展
*
* @author 张荣华(ahuaxuan)
* @since 2007-7-11
* @version $Id$
*/
public class EmailEntity extends EmailRunner{
/**
* 构造简单文本邮件
* @param simpleMailMessage
*/
public void generateSimpleMailMessage(JavaMailSender javaMailSender, ExecutorService executorService) {
super.javaMailSender = javaMailSender;
super.executorService = executorService;
simpleMailMessage = new SimpleMailMessage();
simpleMailMessage.setTo(to);
simpleMailMessage.setSubject(subject);
simpleMailMessage.setText(text);
simpleMailMessage.setFrom(from);
}
/**
* 构造复杂邮件,可以添加附近,图片,等等
* @param mimeMessage
* @throws MessagingException
*/
public void generateMimeMailMessage(JavaMailSender javaMailSender, ExecutorService executorService) throws MessagingException {
super.javaMailSender = javaMailSender;
super.executorService = executorService;
MimeMessage message = javaMailSender.createMimeMessage();
MimeMessageHelper helper = new MimeMessageHelper(message);
helper.setTo(to);
helper.setFrom(from);
helper.setSubject(subject);
super.addAttachmentOrImg(helper, attachment, true);
super.addAttachmentOrImg(helper, img, false);
//这里的text是html格式的, 可以使用模板引擎来生成html模板, velocity或者freemarker都可以做到
helper.setText(text);
}
/**
* 发送邮件方法, 在这个方法调用之前必须调用 generateMimeMailMessage 或者 generateSimpleMailMessage,
* @see EasyMailServiceImpl#sendMimeMessage(EmailEntity)
* @see EasyMailServiceImpl#sendMessage(EmailEntity)
*/
public void send() {
if(super.javaMailSender != null && super.executorService != null){
super.executorService.execute(this);
}
}
}
/**
* 该类是对邮件的抽象,邮件有哪些属性,这个类就有哪些属性 显然这个只是一个例子,
* 这个例子中附带mimemessage发送所需的附件或者图片(如果有的话)
* 需要使用的同学自己扩展
*
* @author 张荣华(ahuaxuan)
* @since 2007-7-11
* @version $Id$
*/
public class EmailEntity extends EmailRunner{
/**
* 构造简单文本邮件
* @param simpleMailMessage
*/
public void generateSimpleMailMessage(JavaMailSender javaMailSender, ExecutorService executorService) {
super.javaMailSender = javaMailSender;
super.executorService = executorService;
simpleMailMessage = new SimpleMailMessage();
simpleMailMessage.setTo(to);
simpleMailMessage.setSubject(subject);
simpleMailMessage.setText(text);
simpleMailMessage.setFrom(from);
}
/**
* 构造复杂邮件,可以添加附近,图片,等等
* @param mimeMessage
* @throws MessagingException
*/
public void generateMimeMailMessage(JavaMailSender javaMailSender, ExecutorService executorService) throws MessagingException {
super.javaMailSender = javaMailSender;
super.executorService = executorService;
MimeMessage message = javaMailSender.createMimeMessage();
MimeMessageHelper helper = new MimeMessageHelper(message);
helper.setTo(to);
helper.setFrom(from);
helper.setSubject(subject);
super.addAttachmentOrImg(helper, attachment, true);
super.addAttachmentOrImg(helper, img, false);
//这里的text是html格式的, 可以使用模板引擎来生成html模板, velocity或者freemarker都可以做到
helper.setText(text);
}
/**
* 发送邮件方法, 在这个方法调用之前必须调用 generateMimeMailMessage 或者 generateSimpleMailMessage,
* @see EasyMailServiceImpl#sendMimeMessage(EmailEntity)
* @see EasyMailServiceImpl#sendMessage(EmailEntity)
*/
public void send() {
if(super.javaMailSender != null && super.executorService != null){
super.executorService.execute(this);
}
}
}
再看看其父类中方法,这个就是executor要执行得代码了:
Java代码
/**
* 该方法将在线程池中的线程中执行
*/
public void run() {
try {
if (simpleMailMessage != null) {
javaMailSender.send(this.simpleMailMessage);
} else if (mimeMessage != null) {
javaMailSender.send(this.mimeMessage);
}
} catch (Exception e) {
if (logger.isDebugEnabled()) {
logger.debug("logger something here", e);
}
}
}
这篇文章的名字起得很古怪(估计还有人暗地里说文章名字取得如何如何,文章实质却是水货等等了,先不忙下结论,各位看官接着往下看便知),叫简单和复杂之间,为什么要取这么个奇怪的名字,搞得人一头雾水,其实我想要表达的意思是这样的,之前坛子上有很多人讨论过如何使用javamail(包括spring对其的封装),也有人讨论过如何通过jms发送emal,一个是简单的api介绍,一个是比较复杂的异步方案,但是试问除了简单使用其api难道就只能使用jms来进行异步发送了吗,我们可以再找到一种介于这两者之间的方案,就是concurrent(我的建议是在普通的web应用中邮件发送不需要用jms,但是最好也不要使用同步发送,所以普通的web应该使用concurrent来进行异步邮件发送应该是比较好的选择)。
在普通的web应用中,发送邮件应该只能算小任务,而使用jms来发送邮件有点杀鸡用牛刀的味道,那么如果能建立一个线程池来管理这些小线程并重复使用他们,应该来说是一个简单有效的方案,我们可以使用concurrent包中的Executors来建立线程池,Executors是一个工厂,也是一个工具类,我把它的api的介绍简单的翻译了一下(如果翻译有误请大家不要吝啬手中的砖头)
方 法 说 明
newCachedThreadPool() 创建一个包含新线程的线程池,池中线程的数量需要预先指定,该线程池会复用之前创建的线程(前提是该线程还是有效线程)。如果你的要执行的任务是短生命周期的任务的话,使用这种池提高性能是很具代表性的。这个方法有一个重载
newFixedThreadPool() 创建一个线程池以复用指定数量的线程,如果当所有线程都是活动状态时(指这些线程都在运行),那么新的任务将会等待,知道有空余的线程。如果有任何一个线程因为在运行中发生错误而终结(非正常shutdown),那么如果有新的任务要并发处理,concurrent就会创建一个新的线程放入池中。
newSingleThreadExecutor() 创建一个使用单工作线程的executor,
newScheduledThreadPool() 可调度的线程池,池中的线程可以在某一时间延迟之后执行,也可以周期性执行
newSingleThreadScheduledExecutor() 单一可调度的线程
上面我重点解释了newFixedThreadPool(),因为我们将使用newFixedThreadPool方法来创建一个线程池,这个线程池中存放的线程就是我们用来发送邮件的。代码如下:
Java代码
/**
* 由spring管理的线程池类,返回的ExecutorService就是给我们来执行线程的
*如果不交给spring管理也是可以的,可以使用单例模式来实现同样功能,但是poolSize *要hardcode了
* @author 张荣华(ahuaxuan)
* @version $Id$
*/
public class EasyMailExecutorPool implements InitializingBean {
//线程池大小,spring配置文件中配置
private int poolSize;
private ExecutorService service;
public ExecutorService getService() {
return service;
}
public int getPoolSize() {
return poolSize;
}
public void setPoolSize(int poolSize) {
this.poolSize = poolSize;
}
/**
* 在 bean 被初始化成功之后初始化线程池大小
*/
public void afterPropertiesSet() throws Exception {
service = Executors.newFixedThreadPool(poolSize);
}
}
/**
* 由spring管理的线程池类,返回的ExecutorService就是给我们来执行线程的
*如果不交给spring管理也是可以的,可以使用单例模式来实现同样功能,但是poolSize *要hardcode了
* @author 张荣华(ahuaxuan)
* @version $Id$
*/
public class EasyMailExecutorPool implements InitializingBean {
//线程池大小,spring配置文件中配置
private int poolSize;
private ExecutorService service;
public ExecutorService getService() {
return service;
}
public int getPoolSize() {
return poolSize;
}
public void setPoolSize(int poolSize) {
this.poolSize = poolSize;
}
/**
* 在 bean 被初始化成功之后初始化线程池大小
*/
public void afterPropertiesSet() throws Exception {
service = Executors.newFixedThreadPool(poolSize);
}
}
这样我们就初始化了线程池的大小,接下来就是如何使用这个线程池中的线程了,我们看看MailService是如何来使用线程池中的线程的,这个类中的代码我已经作了详细的解释
Java代码
/**
* 用来发送 mail 的 service, 其中有一个内部类专门用来供线程使用
* @author 张荣华(ahuaxuan)
* @since 2007-7-11
* @version $Id$
*/
public class EasyMailServieImpl implements EasyMailService{
private static transient Log logger = LogFactory.getLog(EasyMailServieImpl.class);
//注入MailSender
private JavaMailSender javaMailSender;
//注入线程池
private EasyMailExecutorPool easyMailExecutorPool;
//设置发件人
private String from;
public void setEasyMailExecutorPool(EasyMailExecutorPool easyMailExecutorPool) {
this.easyMailExecutorPool = easyMailExecutorPool;
}
public void setJavaMailSender(JavaMailSender javaMailSender) {
this.javaMailSender = javaMailSender;
}
public void setFrom(String from) {
this.from = from;
}
/**
* 简单的邮件发送接口,感兴趣的同学可以在这个基础上继续添加
* @param to
* @param subject
* @param text
*/
public void sendMessage(EmailEntity email){
if (null == email) {
if (logger.isDebugEnabled()) {
logger.debug("something you need to tell here");
}
return;
}
SimpleMailMessage simpleMailMessage = new SimpleMailMessage();
simpleMailMessage.setTo(email.getTo());
simpleMailMessage.setSubject(email.getSubject());
simpleMailMessage.setText(email.getText());
simpleMailMessage.setFrom(from);
easyMailExecutorPool.getService().execute(new MailRunner(simpleMailMessage));
}
/**
* 发送复杂格式邮件的接口,可以添加附件,图片,等等,但是需要修改这个方法,
* 如何做到添加附件和图片论坛上有例子了,需要的同学搜一下,
* 事实上这里的text参数最好是来自于模板,用模板生成html页面,然后交给javamail去发送,
* 如何使用模板来生成html见 {@link http://www.iteye.com/topic/71430 }
*
* @param to
* @param subject
* @param text
* @throws MessagingException
*/
public void sendMimeMessage(EmailEntity email) throws MessagingException {
if (null == email) {
if (logger.isDebugEnabled()) {
logger.debug("something you need to tell here");
}
return;
}
MimeMessage message = javaMailSender.createMimeMessage();
MimeMessageHelper helper = new MimeMessageHelper(message);
helper.setTo(email.getTo());
helper.setFrom(from);
helper.setSubject(email.getSubject());
this.addAttachmentOrImg(helper, email.getAttachment(), true);
this.addAttachmentOrImg(helper, email.getImg(), false);
//这里的text是html格式的, 可以使用模板引擎来生成html模板, velocity或者freemarker都可以做到
helper.setText(email.getText(),true);
easyMailExecutorPool.getService().execute(new MailRunner(message));
}
/**
* 添加附件或者是图片
* @param helper
* @param map
* @param isAttachment
* @throws MessagingException
*/
private void addAttachmentOrImg(MimeMessageHelper helper, Map map, boolean isAttachment) throws MessagingException {
for (Iterator it = map.entrySet().iterator(); it.hasNext();) {
Map.Entry entry = (Map.Entry) it.next();
String key = (String) entry.getKey();
String value = (String) entry.getValue();
if (StringUtils.isNotBlank(key) && StringUtils.isNotBlank(value)) {
FileSystemResource file = new FileSystemResource(new File(value));
if (!file.exists()) continue;
if (isAttachment) {
helper.addAttachment(key, file);
} else {
helper.addInline(key, file);
}
}
}
}
/**
* 用来发送邮件的 Runnable, 该类是一个内部类,之所以使用内部类,而没有使用嵌套类(静态内部类),
* 是因为内部类可以之间得到 service 的 javaMailSender
* 每次发送邮件都会从线程池中取一个线程, 然后进行发邮件操作
* @author ahuaxuan
*/
private class MailRunner implements Runnable {
SimpleMailMessage simpleMailMessage;
MimeMessage mimeMessage;
/**
* 构造简单文本邮件
* @param simpleMailMessage
*/
public MailRunner(SimpleMailMessage simpleMailMessage) {
if (mimeMessage == null) {
this.simpleMailMessage = simpleMailMessage;
}
}
/**
* 构造复杂邮件,可以添加附近,图片,等等
* @param mimeMessage
*/
public MailRunner(MimeMessage mimeMessage) {
if (simpleMailMessage == null) {
this.mimeMessage = mimeMessage;
}
}
/**
* 该方法将在线程池中的线程中执行
*/
public void run() {
try {
if (simpleMailMessage != null) {
javaMailSender.send(this.simpleMailMessage);
} else if (mimeMessage != null) {
javaMailSender.send(this.mimeMessage);
}
} catch (Exception e) {
if (logger.isDebugEnabled()) {
logger.debug("logger something here", e);
}
}
}
}
}
/**
* 用来发送 mail 的 service, 其中有一个内部类专门用来供线程使用
* @author 张荣华(ahuaxuan)
* @since 2007-7-11
* @version $Id$
*/
public class EasyMailServieImpl implements EasyMailService{
private static transient Log logger = LogFactory.getLog(EasyMailServieImpl.class);
//注入MailSender
private JavaMailSender javaMailSender;
//注入线程池
private EasyMailExecutorPool easyMailExecutorPool;
//设置发件人
private String from;
public void setEasyMailExecutorPool(EasyMailExecutorPool easyMailExecutorPool) {
this.easyMailExecutorPool = easyMailExecutorPool;
}
public void setJavaMailSender(JavaMailSender javaMailSender) {
this.javaMailSender = javaMailSender;
}
public void setFrom(String from) {
this.from = from;
}
/**
* 简单的邮件发送接口,感兴趣的同学可以在这个基础上继续添加
* @param to
* @param subject
* @param text
*/
public void sendMessage(EmailEntity email){
if (null == email) {
if (logger.isDebugEnabled()) {
logger.debug("something you need to tell here");
}
return;
}
SimpleMailMessage simpleMailMessage = new SimpleMailMessage();
simpleMailMessage.setTo(email.getTo());
simpleMailMessage.setSubject(email.getSubject());
simpleMailMessage.setText(email.getText());
simpleMailMessage.setFrom(from);
easyMailExecutorPool.getService().execute(new MailRunner(simpleMailMessage));
}
/**
* 发送复杂格式邮件的接口,可以添加附件,图片,等等,但是需要修改这个方法,
* 如何做到添加附件和图片论坛上有例子了,需要的同学搜一下,
* 事实上这里的text参数最好是来自于模板,用模板生成html页面,然后交给javamail去发送,
* 如何使用模板来生成html见 {@link http://www.iteye.com/topic/71430 }
*
* @param to
* @param subject
* @param text
* @throws MessagingException
*/
public void sendMimeMessage(EmailEntity email) throws MessagingException {
if (null == email) {
if (logger.isDebugEnabled()) {
logger.debug("something you need to tell here");
}
return;
}
MimeMessage message = javaMailSender.createMimeMessage();
MimeMessageHelper helper = new MimeMessageHelper(message);
helper.setTo(email.getTo());
helper.setFrom(from);
helper.setSubject(email.getSubject());
this.addAttachmentOrImg(helper, email.getAttachment(), true);
this.addAttachmentOrImg(helper, email.getImg(), false);
//这里的text是html格式的, 可以使用模板引擎来生成html模板, velocity或者freemarker都可以做到
helper.setText(email.getText(),true);
easyMailExecutorPool.getService().execute(new MailRunner(message));
}
/**
* 添加附件或者是图片
* @param helper
* @param map
* @param isAttachment
* @throws MessagingException
*/
private void addAttachmentOrImg(MimeMessageHelper helper, Map map, boolean isAttachment) throws MessagingException {
for (Iterator it = map.entrySet().iterator(); it.hasNext();) {
Map.Entry entry = (Map.Entry) it.next();
String key = (String) entry.getKey();
String value = (String) entry.getValue();
if (StringUtils.isNotBlank(key) && StringUtils.isNotBlank(value)) {
FileSystemResource file = new FileSystemResource(new File(value));
if (!file.exists()) continue;
if (isAttachment) {
helper.addAttachment(key, file);
} else {
helper.addInline(key, file);
}
}
}
}
/**
* 用来发送邮件的 Runnable, 该类是一个内部类,之所以使用内部类,而没有使用嵌套类(静态内部类),
* 是因为内部类可以之间得到 service 的 javaMailSender
* 每次发送邮件都会从线程池中取一个线程, 然后进行发邮件操作
* @author ahuaxuan
*/
private class MailRunner implements Runnable {
SimpleMailMessage simpleMailMessage;
MimeMessage mimeMessage;
/**
* 构造简单文本邮件
* @param simpleMailMessage
*/
public MailRunner(SimpleMailMessage simpleMailMessage) {
if (mimeMessage == null) {
this.simpleMailMessage = simpleMailMessage;
}
}
/**
* 构造复杂邮件,可以添加附近,图片,等等
* @param mimeMessage
*/
public MailRunner(MimeMessage mimeMessage) {
if (simpleMailMessage == null) {
this.mimeMessage = mimeMessage;
}
}
/**
* 该方法将在线程池中的线程中执行
*/
public void run() {
try {
if (simpleMailMessage != null) {
javaMailSender.send(this.simpleMailMessage);
} else if (mimeMessage != null) {
javaMailSender.send(this.mimeMessage);
}
} catch (Exception e) {
if (logger.isDebugEnabled()) {
logger.debug("logger something here", e);
}
}
}
}
}
MailService中的EmailEntity是对邮件的抽象(我只使用了失血模型,事实上我们也可以让这个EmailEntity来实现Runnable接口,这样Service中的内部类就可以去掉了,同时service中的大部分代码就要搬到EmailEntity及其父类里了,大家更倾向于怎么做呢?),代码如下:
Java代码
/**
* 该类是对邮件的抽象,邮件有哪些属性,这个类就有哪些属性 显然这个只是一个例子,
* 这个例子中附带mimemessage发送所需的附件或者图片(如果有的话)
* 需要使用的同学自己扩展
*
* @author 张荣华(ahuaxuan)
* @version $Id$
*/
public class EmailEntity {
String to;
String subject;
String text;
//邮件附件
Map<String, String> attachment = new HashMap<String, String>();
//邮件图片
Map<String, String> img = new HashMap<String, String>();
//这里省去大段的getter和setter方法
}
/**
* 该类是对邮件的抽象,邮件有哪些属性,这个类就有哪些属性 显然这个只是一个例子,
* 这个例子中附带mimemessage发送所需的附件或者图片(如果有的话)
* 需要使用的同学自己扩展
*
* @author 张荣华(ahuaxuan)
* @version $Id$
*/
public class EmailEntity {
String to;
String subject;
String text;
//邮件附件
Map<String, String> attachment = new HashMap<String, String>();
//邮件图片
Map<String, String> img = new HashMap<String, String>();
//这里省去大段的getter和setter方法
}
接下来就是在spring的配置文件中配置这些类了,我相信对熟悉spring的人来说这不是什么大问题:
Java代码
<beans>
<bean id="javaMailSender" class="org.springframework.mail.javamail.JavaMailSenderImpl" autowire="byName">
<property name="host" value="${mail.host}"/>
<property name="username" value="${mail.username}"/>
<property name="password" value="${mail.password}"/>
</bean>
<bean id="easyMailExecutorPool" class="org.zhangronghua.easymail.EasyMailExecutorPool" autowire="byName">
<property name="poolSize">
<value>5</value>
</property>
</bean>
<bean id="easyMailService" class="org.zhangronghua.easymail.EasyMailServieImpl" autowire="byName">
<property name="from" value="${mail.default.from}"/>
</bean>
</beans>
<beans>
<bean id="javaMailSender" class="org.springframework.mail.javamail.JavaMailSenderImpl" autowire="byName">
<property name="host" value="${mail.host}"/>
<property name="username" value="${mail.username}"/>
<property name="password" value="${mail.password}"/>
</bean>
<bean id="easyMailExecutorPool" class="org.zhangronghua.easymail.EasyMailExecutorPool" autowire="byName">
<property name="poolSize">
<value>5</value>
</property>
</bean>
<bean id="easyMailService" class="org.zhangronghua.easymail.EasyMailServieImpl" autowire="byName">
<property name="from" value="${mail.default.from}"/>
</bean>
</beans>
经过这么一番折腾之后,一个邮件发送的雏形就完成了,接着需要什么样的邮件发送功能就可以随意往MailService里添加内容了, 而如果需要用模板来生成html格式的邮件真的需要看http://www.iteye.com/topic/71430这个贴了,无论你是想用velocity还是想用freemarker来做模板引擎,这个贴中的例子都是可以直接拿来使用的
总结,如果自己起线程来发送邮件是一个非常危险的事情,如果并发一高(比如超过20),服务器估计就快撑不住了,而如果使用jms来异步发送邮件,学习的曲线高,成本也高,我不建议为了一个小小的邮件发送就在项目中导入jms(之所以这样说是因为还有很多项目就是基于webservice的,那么使用jms来调度webservice是一个不错的选择),所以使用线程池来实现这个异步的功能既安全又简单,这个例子是开源的,大家可以在自己的项目中随意修改,随意封装。
要注意的是,concurrent在jdk5.0以上版本中才有,如果你使用的是1.4的jdk需要单独下载concurrent包。
作者:张荣华,未经作者同意不得随意转载!
声明:JavaEye文章版权属于作者,受法律保护。没有作者书面许可不得转载。
推荐链接: 参加微软MSN机器人大赛,挑战你的想象力!赢取HP笔记本大奖!
推荐链接: qinysong :基于开源工作流引擎OSWorkflow的业务系统实例——请假审批系统您每点击一次,微软即为慈善事业捐出一分钱!
返回顶楼
ahuaxuan
等级:
性别:
文章: 549
积分: 1296
来自: 上海
时间:2007-07-12 收藏 收入博客 昨天发的帖子说错了一个概念:上面例子中其实使用的是失血模型,我说成了贫血模型,在此更正一下,经过思考,我觉得对这个邮件的抽象用真正的贫血模型是比较合适的,也比失血模型更加的oo,而且代码我也已经重构过了,重构完之后发现最后的结果是整个就是一strategy+adapter,最后service中的方法变成了这个德行(service中的方法变成了策略的调用者)
Java代码
public void sendMimeMessage(EmailEntity email) throws MessagingException {
email.setFrom(from);
email.generateMimeMailMessage(javaMailSender, easyMailExecutorPool.getService());
email.send();
}
public void sendMimeMessage(EmailEntity email) throws MessagingException {
email.setFrom(from);
email.generateMimeMailMessage(javaMailSender, easyMailExecutorPool.getService());
email.send();
}
方法都跑EmailEntity和其父类中去了,但是我没有办法在Entity中注入需要的service,只要作为参数传了进去,从整体上来看,整个easymail变得更加得面向对象了。这让我体会到贫血模型确实要比失血模型更oo
我们看看EmailEntity中得代码:
Java代码
/**
* 该类是对邮件的抽象,邮件有哪些属性,这个类就有哪些属性 显然这个只是一个例子,
* 这个例子中附带mimemessage发送所需的附件或者图片(如果有的话)
* 需要使用的同学自己扩展
*
* @author 张荣华(ahuaxuan)
* @since 2007-7-11
* @version $Id$
*/
public class EmailEntity extends EmailRunner{
/**
* 构造简单文本邮件
* @param simpleMailMessage
*/
public void generateSimpleMailMessage(JavaMailSender javaMailSender, ExecutorService executorService) {
super.javaMailSender = javaMailSender;
super.executorService = executorService;
simpleMailMessage = new SimpleMailMessage();
simpleMailMessage.setTo(to);
simpleMailMessage.setSubject(subject);
simpleMailMessage.setText(text);
simpleMailMessage.setFrom(from);
}
/**
* 构造复杂邮件,可以添加附近,图片,等等
* @param mimeMessage
* @throws MessagingException
*/
public void generateMimeMailMessage(JavaMailSender javaMailSender, ExecutorService executorService) throws MessagingException {
super.javaMailSender = javaMailSender;
super.executorService = executorService;
MimeMessage message = javaMailSender.createMimeMessage();
MimeMessageHelper helper = new MimeMessageHelper(message);
helper.setTo(to);
helper.setFrom(from);
helper.setSubject(subject);
super.addAttachmentOrImg(helper, attachment, true);
super.addAttachmentOrImg(helper, img, false);
//这里的text是html格式的, 可以使用模板引擎来生成html模板, velocity或者freemarker都可以做到
helper.setText(text);
}
/**
* 发送邮件方法, 在这个方法调用之前必须调用 generateMimeMailMessage 或者 generateSimpleMailMessage,
* @see EasyMailServiceImpl#sendMimeMessage(EmailEntity)
* @see EasyMailServiceImpl#sendMessage(EmailEntity)
*/
public void send() {
if(super.javaMailSender != null && super.executorService != null){
super.executorService.execute(this);
}
}
}
/**
* 该类是对邮件的抽象,邮件有哪些属性,这个类就有哪些属性 显然这个只是一个例子,
* 这个例子中附带mimemessage发送所需的附件或者图片(如果有的话)
* 需要使用的同学自己扩展
*
* @author 张荣华(ahuaxuan)
* @since 2007-7-11
* @version $Id$
*/
public class EmailEntity extends EmailRunner{
/**
* 构造简单文本邮件
* @param simpleMailMessage
*/
public void generateSimpleMailMessage(JavaMailSender javaMailSender, ExecutorService executorService) {
super.javaMailSender = javaMailSender;
super.executorService = executorService;
simpleMailMessage = new SimpleMailMessage();
simpleMailMessage.setTo(to);
simpleMailMessage.setSubject(subject);
simpleMailMessage.setText(text);
simpleMailMessage.setFrom(from);
}
/**
* 构造复杂邮件,可以添加附近,图片,等等
* @param mimeMessage
* @throws MessagingException
*/
public void generateMimeMailMessage(JavaMailSender javaMailSender, ExecutorService executorService) throws MessagingException {
super.javaMailSender = javaMailSender;
super.executorService = executorService;
MimeMessage message = javaMailSender.createMimeMessage();
MimeMessageHelper helper = new MimeMessageHelper(message);
helper.setTo(to);
helper.setFrom(from);
helper.setSubject(subject);
super.addAttachmentOrImg(helper, attachment, true);
super.addAttachmentOrImg(helper, img, false);
//这里的text是html格式的, 可以使用模板引擎来生成html模板, velocity或者freemarker都可以做到
helper.setText(text);
}
/**
* 发送邮件方法, 在这个方法调用之前必须调用 generateMimeMailMessage 或者 generateSimpleMailMessage,
* @see EasyMailServiceImpl#sendMimeMessage(EmailEntity)
* @see EasyMailServiceImpl#sendMessage(EmailEntity)
*/
public void send() {
if(super.javaMailSender != null && super.executorService != null){
super.executorService.execute(this);
}
}
}
再看看其父类中方法,这个就是executor要执行得代码了:
Java代码
/**
* 该方法将在线程池中的线程中执行
*/
public void run() {
try {
if (simpleMailMessage != null) {
javaMailSender.send(this.simpleMailMessage);
} else if (mimeMessage != null) {
javaMailSender.send(this.mimeMessage);
}
} catch (Exception e) {
if (logger.isDebugEnabled()) {
logger.debug("logger something here", e);
}
}
}
- 桌面.rar (2.4 KB)
- 描述: javamail,log4j
- 下载次数: 26
评论
3 楼
wa114d
2012-10-25
能不能把你源码放上啊,谢谢啊
2 楼
cfyme
2012-07-04
重构过的代码 我去运行 怎么也执行不到EmailRunner中的run方法,能把您重构后的代码发我一份吗,cfyme@163.com
1 楼
cfyme
2012-07-04
大师,你有没有源文件 你上传附件不是正确的
发表评论
-
eclipse快捷键
2009-02-03 09:17 1059作用域 功能 快捷键 全局 查找并替换 Ctrl+F 文本 ... -
Java随机码
2009-01-21 10:26 1604package servlet; import java.a ... -
java时间
2009-01-21 10:24 10691. package com.hefeng.test ... -
fastExcel
2009-01-21 10:22 12161. public void testFastExcel ... -
类到底是从哪个Jar包或者目录下装载的
2009-01-11 09:54 941aClass.getProtectionDomain().ge ... -
生成可执行jar文件的教程
2008-12-11 09:27 1023若要生成一个名为 cal.jar 的可执行jar文件:(文件名 ... -
软件智力面试题及答案
2008-08-28 11:29 1181第一组 1.烧一根不均匀的绳,从头烧到尾总共需要1个小时。 ... -
word,excel,pdf
2008-08-28 09:59 10121、一个jacob操作Word的例子,其他操作excel,pd ... -
prototype.js参考
2008-08-22 16:42 1282<!DOCTYPE HTML PUBLIC " ... -
各类Http请求状态(status)及其含义
2008-08-22 16:18 1120AJAX中请求远端文件、或在检测远端文件是否掉链时,都需要了解 ... -
Eclips反编译插件的安装
2008-06-26 09:23 1226大家也许用过其他的反编译工具,比如jad,或者是集成的DJ J ... -
Java反射学习
2008-03-14 10:09 1934Java反射学习 Java反射学 ... -
java性能小知识
2008-02-28 09:47 926Vector v=new Vector(); for(int ... -
qq,msn,skype即时消息
2008-02-19 16:13 1115详细信息请见附件 -
java union and intersection
2008-01-18 09:50 2734String[] arrayA = new String[] ... -
Java中如何正确使用字体编码
2007-12-21 09:16 1222首先声明一下,此文章时从网上转载的。如下的某些方法是确实管 ... -
cvs搭建过程
2007-09-26 11:05 1143一。附件是安装文件 二。建资源库,可在任何地方。 三。set ... -
代码控制来改变应用程序的当前工作目录
2007-09-03 09:34 1073System.setProperty("user.d ... -
java file or folder
2007-08-28 13:21 1465import java.io.*; public class ... -
java调用存储过程
2007-08-20 09:12 708DBOperator db = new DBOperator( ...
相关推荐
JavaMail 是一个强大的开源库,用于在Java应用程序中实现电子邮件的发送和接收功能。它提供了丰富的API,使得开发者能够方便地处理SMTP、POP3、IMAP等邮件协议,支持多种邮件格式,包括文本、HTML以及带有附件的邮件...
JavaMail 是一个开源的 Java API,它为开发者提供了在 Java 应用程序中发送和接收电子邮件的功能。这个API包括了多种协议的支持,如SMTP(简单邮件传输协议)、POP3(邮局协议)和IMAP(因特网消息访问协议)。在...
JavaMail 是一个开源的 Java API,它为Java程序员提供了邮件收发功能,使得开发者能够方便地集成电子邮件功能到他们的应用程序中。这个标题提到的是JavaMail的1.4.3版本,其中包含了mail.jar库文件以及对应的源代码...
JavaMail 是一个开源的 Java API,它允许开发者在 Java 应用程序中发送和接收电子邮件。这个【标题】"JavaMail所需最新版(1.5.4)jar包"指的是包含JavaMail 1.5.4版本所需的所有库文件的集合,确保开发者能够使用这...
JavaMail API 1.4.7 是一个广泛使用的开源库,专为Java开发者设计,用于处理电子邮件相关的任务。这个版本的API提供了丰富的功能,包括发送、接收邮件,管理邮箱,处理附件,以及支持多种邮件协议如SMTP(简单邮件...
使用 JavaMail 代发邮件 使用 JavaMail 库可以轻松地在 Java 应用程序中发送电子邮件。JavaMail 是一个 Java API,用于在 Java 应用程序中发送和接收电子邮件。它提供了一个抽象层,允许开发者使用不同的电子邮件...
JavaMail API是Java平台上用于发送和接收电子邮件的一个标准扩展库。它并不是Java标准库的一部分,而是Java企业版(J2EE)中的一部分。JavaMail提供了一系列用于处理电子邮件的类和接口,允许开发者在Java应用程序中...
JavaMail 是一个开源的 Java API,它允许 Java 程序员通过 SMTP、POP3 或 IMAP 协议发送、接收和管理电子邮件。这个压缩包包含了一组与 JavaMail 相关的源代码和必要的库文件,使得开发者可以快速地理解和实现邮件...
JavaMail 是一个开源库,用于在Java应用程序中处理电子邮件。这个库提供了丰富的API,使得开发者可以方便地执行发送、接收、读取和管理邮件的任务。`javamail-1.6`是JavaMail的一个版本,它包含了从早期版本中继承的...
JavaMail 是一个开源的Java库,它为Java程序员提供了处理电子邮件的能力。这个库不仅支持SMTP、POP3和IMAP协议,还支持其他的邮件系统协议,如NNTP和EWS。JavaMail API是JavaMail库的核心部分,它提供了一系列的接口...
基于Javamail的邮件收发系统.zip基于Javamail的邮件收发系统.zip基于Javamail的邮件收发系统.zip基于Javamail的邮件收发系统.zip基于Javamail的邮件收发系统.zip基于Javamail的邮件收发系统.zip基于Javamail的邮件...
JavaMail 是一个开源的 Java 库,用于处理电子邮件的发送和接收。它提供了与 SMTP、POP3 和 IMAP 协议交互的接口,是开发基于 Java 的电子邮件应用的基础。回执邮件是邮件服务中的一项功能,它允许发件人在发送邮件...
JavaMail API是Java平台上用于处理电子邮件的一套标准API,它为开发者提供了丰富的接口和类,以便于发送、接收和管理电子邮件。JavaMail API是Java EE的一部分,但也可以在Java SE环境中使用。`javaMail.jar`是...
JavaMail 是一个开源的 Java API,它为Java开发者提供了处理电子邮件的能力。这个API允许开发者发送、接收、管理邮件,包括附件、HTML 内容、MIME 多部分消息等。`javamail.jar` 文件是JavaMail的核心库,包含了所有...
JavaMail API是Java平台上用于处理电子邮件的一套强大的库,它为开发者提供了丰富的功能,使得在应用程序中发送和接收邮件变得简单。本文将深入探讨JavaMail API的各个方面,帮助你理解和掌握这一关键工具。 首先,...
JavaMail 是一个强大的开源库,用于在Java应用程序中处理电子邮件。它支持多种协议,包括POP3、IMAP和SMTP,这些协议分别用于接收、检索和发送邮件。在使用JavaMail时,了解如何进行加密和非加密通信对于确保数据...
JavaMail是Java编程语言中用于处理电子邮件的API,它提供了丰富的功能,允许开发人员发送、接收和管理电子邮件。本篇文章将深入探讨JavaMail的核心概念、关键组件以及如何使用这两个特定的jar包——`jaf-1_1_1.zip`...
JavaMail是Java编程环境中用于处理电子邮件的一套API,它提供了丰富的功能,允许开发者发送、接收和操作邮件。在JavaMail的实现中,通常会用到三个关键的JAR包:`activation-1.1.jar`、`javax.mail-api-1.5.6.jar`和...
JavaMail 是一个强大的开源库,专门用于在Java应用程序中处理电子邮件。这个完整JAR包包含了所有必要的组件,使得开发者能够方便地实现发送、接收、读取以及管理电子邮件。以下是JavaMail的一些关键知识点: 1. **...
JavaMail 是一个开源的 Java API,它为开发者提供了在 Java 应用程序中发送和接收电子邮件的能力。这个“JavaMail 1.6.0 Final Release”是 JavaMail 的一个重要版本,它包含了对 SMTP(简单邮件传输协议)、IMAP...