邮件发送文档
- 格式:doc
- 大小:107.00 KB
- 文档页数:18
利用Spring框架封装的JavaMail现实同步或异步邮件发送
作者:张纪豪
J2EE简单地讲是在JDK上扩展了各类应用的标准规范,邮件处理便是其中一个重要的应用。它既然是规范,那么我们就可以通过JDK遵照邮件协议编写一个邮件处理系统,但事实上已经有很多厂商和开源组织这样做了。Apache是J2EE最积极的实现者之一,当然还有我们的老大——SUN。
聊起老大,感慨万端!他已经加入Oracle——甲骨文(不是刻在乌龟壳上的那种文字吗?是我中华,也是人类上最早的语言啊,比Java早几千年哦),其掌门人拉里·埃里森是个不错的水手,别以为那只是在帆船上,至少他不至于盖茨那么不仁道——开源万岁。有理由相信Java世界还有一段辉煌的历程。Google的Android和Chrome OS两大操作系统,还会首选Java作应用开发基础语言,即便是推出自己的易语言。同时笔者预感到ChromeOS前景不可估量,它可能是推动云计算一个重要组成部分,Andtroid(主用在移动设备上,未来可能是手机上主流的操作系统),乃至微软的Windows将来可能都是该系统的小窗口而已。微软已显得老态龙钟了,再与大势已去的雅虎合作,前进步伐必将大大减缓。投资者此时可以长线买入Google股票(投资建议,必自判断)。笔者也常用google搜索引擎、gmail。
好了,闲话少聊,言归主题。
可能大家如笔者一样用的最多的是老大的javamail,虽然老大实现了邮件功能,但调用起来还是需要较复杂的代码来完成,而且初学者调用成功率很低(因为它还要与外界服务器通信),这就使得初学者对于它越学越迷茫。不过这
方面的例子很多,因此笔者不再在此重复这些示例代码,而着重利用Spring框架封装的邮件处理功能。
开工之前,我们先了解下环境。笔者开的是web工程,所需要的基础配置如下:
▲ JDK 1.6
▲ J2EE 1.5
▲ JavaMail 1.4 稍作说明:J2EE 1.5中已经纳入了邮件规范,因此在开发期不要导入javamail中的jar包,运行期则需要,因此可以将jar包放入到web容器的java库中(例如Tomcat的lib目录下),要了解其意可以参考数据库驱动包的运用。文章结尾会对其进一步说明;
▲ Spring 2.5
▲ 一个邮箱 如上所述,笔者爱用Google的Gmail邮箱。
主要文件清单:
■ MailService.java 邮件处理对象接口
■ MailServiceImpl.java 上述实现
■ Email.java 一个普通的JavaBean,用于封装邮件数据,并与html页面中form表单对应
■ MailController.java 动作处理器
■ spring-core-config.xml Spring核心配置
笔者的web工程中,WEB层使用的是Spring @MVC,当然我们仅需要了解其原理,利用servlet或struts框架来做web层动作处理器都能实现。其它的文件,例如web.xml,WEB层配置均略。
下面开始代码:
spring-core-config.xml:
class="org.springframework.mail.javamail.JavaMailSenderImpl">
true
key="mail.smtp.starttls.enable">true
key="mail.smtp.socketFactory.class">.ssl.SSLSocketFactory
class="org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor">
这是邮件处理的两个核心配置,第一个配置(①)是往容器中装配一个JavaMailSender Bean,它就是JavaMail的封装,其中最关键的是装配过程的属性参数,这些属性既要严格遵照JavaMail规范,又要满足邮件提供商的要求,例如SMTP服务器端口是多少、发送时是否要身份验证、服务器是否采用安全连接、连接时是否加密以及采用什么样的加密方式,邮件服务商提供的这些参数直接影响到上述的配置,这往往是新手最容易忽视的环节,因此配置之前一定要到邮件提供商的站点上详细了解邮箱的技术参数。
同步异步发送问题:JavaMail邮件处理是同步的,即用户触发事件、与SMTP Server通信、服务器返回状态消息、程序结束是单线程内,这时往往因Socket通信、服务器业务处理速度等原因而使得处理时间是个未知数。举个简单的应用实例:若用户在提交注册的同时发送一封激活账户邮件,用户有可能不知道是因为邮件服务器那儿阻塞致半天没有反应而以为注册失败并放弃,这将是失败的设计,但异步方式能解决这些问题。异步方式简单地说就是将邮件处理任务交给另外一个线程,J2EE有两种解决方案,一是种利用JMS,JMS可以实现同步和异步的消息处理,将邮件作为一个异步的消息,就可以实现异步邮件发送。JMS属于J2EE的高级应用,所以对于仅以WEB功能的容器还不支持这种服务,例如Tomcat(当然可以找到插件来解决),由于篇幅限制,本文不再牵涉到新的模块。另一种方案是利用JDK中Executor的支持,JDK 5.0后继版本增加了java.util.concurrent一个强大的并发工具包,它包含了执行器、计时器、锁、线程安全队列、线程任务框架等等。Executor——执行器,它可以将任务的“提交”与“执行”分离解耦,我们的邮件处理任务完全可以借用它实现异步执行。而Spring框架提供了封装,见②。下面我们来看如何使用它,代码如下。
MailServiceImpl.java :
package com.zhangjihao.service.impl;
import java.io.IOException;
import javax.annotation.Resource;
import javax.mail.MessagingException;
import javax.mail.internet.MimeMessage;
import mons.logging.Log;
import mons.logging.LogFactory;
import org.springframework.core.io.ByteArrayResource;
import org.springframework.core.task.TaskExecutor;
import org.springframework.mail.javamail.JavaMailSender;
import org.springframework.mail.javamail.MimeMessageHelper;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;
import com.zhangjihao.bean.Email;
import com.zhangjihao.service.MailService;
import com.zhangjihao.util.StringUtil;
/**
* 说明:
*
* @author 张纪豪
* @version
* Build Time Jul 24, 2009
*/
@Service("mailService")
public class MailServiceImpl implements MailService {
@Resource JavaMailSender mailSender;//注入Spring封装的javamail,Spring的xml中已让框架装配
@Resource TaskExecutor taskExecutor;//注入Spring封装的异步执行器
private Log log = LogFactory.getLog(getClass());
private StringBuffer message = new StringBuffer();
public void sendMail(Email email) throws MessagingException,
IOException {
if(email.getAddress() == null || email.getAddress().length == 0){
this.message.append("没有收件人");
return;
}
if(email.getAddress().length > 5){//收件人大于5封时,采用异步发送
sendMailByAsynchronousMode(email);
this.message.append("收件人过多,正在采用异步方式发送...");
}else{
sendMailBySynchronizationMode(email);
this.message.append("正在同步方式发送邮件...");
}
}
/**
* 异步发送
* @see
com.zhangjihao.service.MailService#sendMailByAsynchronousMode(com.zhangjihao.bean.Email)