`

多种方法使用Java发送电子邮件

    博客分类:
  • Java
阅读更多

多种方法使用Java发送电子邮件

     第一件我们需要知道的事情是,通用电子邮件库实际上是包裹在JavaMail外层的API,所以无论我们选择哪种API,我们都需要JavaMail库。您可能还需要JavaBeans激活框架(JavaBeans Activation Framework (JAF)),该框架将负责处理关于邮件选项的更复杂的内容。最后一个在购物列表上的就是通用电子邮件库(Commons Email),您需要从JAF中将JavaMail库中的mail.jarJAF中的activation.jar和通用电子邮件库中的commons-email-1.0.jar添加到classpath的设置中。

     我们现在已经拥有了支持部件的工具包,让我们从使用JavaMail发送简单的电子邮件开始讲解,我们将提出所有的设置放到一个单独的静态类MailSettings当中,这样做将在比较代码的时候容易些。

     在发送电子邮件之前,您还需要知道SMTP服务器的主机名,SMTP服务器是负责将您的邮件发送到外部世界去的机器。

     JavaMail使用了Session类的概念来保存诸如SMTP主机和认证的信息,主要想法是基于会话(Sessions)在Java虚拟机中可以被隔离,这可以阻止恶意代码窃取其他用户在其他会话中的信息,这些信息可能包括用户名和密码等认证信息。但是,您可能会说,在同一时间,我只在Java 虚拟机上运行一个应用程序,而且我相信我的代码。”JavaMail的目的是开发大型的邮件系统,它有一个具有复杂性的关联层,您可以绕过没有经验的用户,我们用以下的例子来说明:

Properties props=new Properties();
props.put("mail.smtp.host",MailSettings.smtpHost);
Session session=Session.getDefaultInstance(props,null);

     此处,并没有创建新的会话,您只是从会话工厂(session factory)中得到并通过Properties的实例来进行设置,我们只对SMTP主机进行了设置和传送,在得到默认的实例的同时创建了一个共享的会话,现在我们可以使用这个会话来创建邮件消息了。

Message message=new MimeMessage(session);

     JavaMail中有一个Message类,各种各样的消息都是它的子类,如果查看了JavaMailAPI,您会发现它只有一个子类: MimeMessageJavaMail是被设计为通用的电子邮件框架的,所以显然存在冗余的抽象。总之,我们已经使用会话创建了一个 MimeMessage,现在我们需要来填充这个消息。

message.setFrom(new InternetAddress (MailSettings.fromAddress, MailSettings.fromName));

     再次利用抽象,JavaMail有一个Address(地址)类,其他所有的地址类型皆源于此,但是我们现在只关心发送国际互联网的电子邮件,所以我们制造一个InternetAddress,这个地址用来表示电子邮件的来源和一个用于显示的个人名字。现自我们来设置邮件将发向何方。

message.setRecipient(Message.RecipientType.TO, new InternetAddress(MailSettings.toAddress));

     地址的抽象将再次出现,我们设定接收器和接收器的类型,从此处开始,至少纯文本的电子邮件可以稳定地传送了,我们只需要设定邮件的标题、信文并打上时间戳。

message.setSubject(MailSettings.messageSubject);
message.setText(MailSettings.messageBody1);
message.setSentDate(new Date());

     此时,我们已经准备好发送消息了。

Transport.send(message);

     这个对Transport类的调用将会去查找适当的会话,并找出如何发送消息,尽管这样做看上去有些不直观。当我们完成这一步的时候,我们的邮件就已经发送出去了。此时,我们还需要添加代码来捕获三种JavaMail可能抛出的异常,它们是AddressException MessagingExceptionUnsupportedEncodingException. 但这就是最基本的使用JavaMail发送邮件的方法。

     现在,让我们来看看如何使用Apache的通用电子邮件软件包(参见MailCommons.java)来完成同样的工作,通用电子邮件库是一系列类的集合,它们基于您所要发送的邮件类型,其中最简单的是SimpleEmail类,不需要建立任何会话或属性列表:

SimpleEmail email=new SimpleEmail();
email.setHostName(MailSettings.smtpHost);

     以上代码创建了我们的邮件并指定它通过我们选定的SMTP服务器发送,因为通用电子邮件库只处理国际互联网的电子邮件,所以就不必在创建InternetAddress实例上浪费时间了,我们可以简单地设定来源地址:

email.setFrom(MailSettings.fromAddress,MailSettings.fromName);

     我们只需要添加一个地址到收信人列表当中,而不是发送接收器的类型:

email.addTo(MailSettings.toAddress);

     同样,设定邮件的标题和信文与发送邮件都很简单。

email.setSubject(MailSettings.messageSubject);
email.setMsg(MailSettings.messageBody1);
email.send();

     我们所需要去捕获的异常只有EmailException这一种,所以,您应该可以看出通过隐藏所有的框架和会话管理,事情变得非常简单并且代码更容易阅读。

     当然,这是我们所能发送的最简单的电子邮件,我们假设SMTP服务器不需要认证,我们发送的邮件只有一个收件人,并没有发送邮件副本。让我们先来看看认证,SMTP认证(SMTP AUTH)需要用户名和密码来发送邮件,在JavaMail中(参见MailJavaMail2.java),需要创建一个认证者(Authenticator)来返回所需的认证证书:

class ForcedAuthenticator extends Authenticator {
public PasswordAuthentication getPasswordAuthentication() {
return new PasswordAuthentication(MailSettings.smtpUsername,
MailSettings.smtpPassword);
}
}

     当我们创建会话的时候,就给出这个认证者的一个实例。

Session session=Session.getDefaultInstance(props,new ForcedAuthenticator());

     然而,这里有一点要注意,这种做法将默认的会话绑定到了该认证者,因此您需要一个指向它的引用(reference)以再次取得这个会话。当然,您也可以转而使用Session.getInstance(),来创建一个唯一的不共享的实例,但是这将依靠您自己来管理会话的实例。

     现在让我们来看看如果使用通用电子邮件库的方法来进行认证(参见MailCommons2.java),您将只看到一行新的语句:

email.setAuthentication(MailSettings.smtpUsername,MailSettings.smtpPassword);这就解决了认证过程的所有痛苦。

     还有另外一种认证方式,那就是使用在邮件服务中的POP-before-SMTP,它并没有实现SMTP AUTH,其实SMTP AUTHSMTP之后的一种扩展,而POP-before-SMTP的工作方式则是将受密码控制的邮件接收者和发送邮件的能力进行绑定,只有当用户经过 POP协议访问某个受密码保护的POP邮件服务器一段时间之后,此用户才能够发送邮件。在JavaMail中,为了发送邮件,你需要编写打开POP信箱的代码,这将涉及JavaMail接收端的工作,我们将在下一篇文章中讲解相关内容;而对于通用电子邮件库来讲,事情就容易得多了:

email.setPopBeforeSMTP(true,popHost,popUsername,popPassword);

     这使您可以操作与POP-before-SMTP相关的所有功能,而根本不需要考虑处理与POP相关的工作。

     让我们再来看看如何设定邮件的抄送收件人,现在JavaMailMessage类有一个setRecipients方法,该方法可以接受一个 InternetAddress的数组,但这样做并不精巧,如果您已经有了一个储存电子邮件地址的字符串数组,那就可以结束这种复杂方法的考验。

ArrayList ccs=new ArrayList();
for(String s:MailSettings.ccAddresses) ccs.add(new InternetAddress(s));
message.setRecipients(Message.RecipientType.CC,
(InternetAddress[]) ccs.toArray(new InternetAddress[ccs.size()]));

     现在让我们来看看通用电子邮件库,我们发现了两件事情:首先,setTosetCcsetBcc方法都使用了InternetAddress的集合作为它们的参数,这样做更符合Java的现行实践;其次,addToaddCcaddBcc方法将创建和添加收件人列表变得轻松。(参见 MailCommons3.java

for(String s:MailSettings.ccAddresses) email.addCc(s);

     这样的代码更加清晰。

     最后,让我们来看看如何发送包含内嵌图片的HTML格式的电子邮件,在此,JavaBeans激活框架将与JavaMail将协同工作,来协助图片的编码。在JavaMailAPI中,我们首先创建一个MimeMultipart的实例,然后创建MimeBodyParts的实例,并将它们组装到MimeMultipart的实例中,所以,嵌入单个图片,比如uk-builder-com.gif这个图片文件,并将它显示在HTML消息中,我们需要完成以下步骤(参见HtmlJavaMail.java

MimeMultipart multipart=new MimeMultipart();
BodyPart msgBodyPart=new MimeBodyPart();
msgBodyPart.setContent("
H1Hi! From HtmlJavaMail/H1
img src=\"cid:logo\"","text/html");
BodyPart embedImage=new MimeBodyPart();
DataSource ds=new URLDataSource(new URL(MailSettings.inlineImage));
embedImage.setDataHandler(new DataHandler(ds));
embedImage.setHeader("Content-ID","");
multipart.addBodyPart(msgBodyPart);
multipart.addBodyPart(embedImage);
message.setContent(multipart);

     第一个BodyPart将它的内容设置为一个字符串和“text/html”的内容类型,注意,在我们设置的HTML代码中,IMG标签指向了一个内容标识符(content-id),这就是MIME(多用途互联网邮件扩充协议)消息部分的名称,该消息将含有GIF格式的标识图文件,为了嵌入这个图片,我们创建了另一个BodyPart和一个JAF的数据源(data source),JAF类库将负责管理内容的工作;然后我们将使用这个DataSourceBodyPart上添加一个DataHandler(数据处理器),这样就可以读出我们的URL所指向的内容了。最后,我们还要在BodyPart的头部设定Content-ID,这样它就可以作为内嵌图片被访问了。我们创建的那些BodyParts将被添加到MimeMultipart的实例中,为此,我们使用setContent()方法而不是调用 setText()方法。最棘手的部分莫过于管理这些内容标识符了,我们在此只完成了嵌入一个图片的工作,但今后每添加一个图片,您都需要在HTML中加入一个BodyPart和一个内容标识符。

     现在让我们来看看使用通用电子邮件库方法的版本(参见HtmlMailCommons.java):

HtmlEmail email=new HtmlEmail();…
String cid=email.embed(new URL(MailSettings.inlineImage),"Builder AU Logo");
email.setHtmlMsg("
H1Hi! From MailJavaMail3/H1><img src=\"cid:"+cid+"\"");
email.setTextMsg("Your email client does not support HTML messages, sorry");

     这种方法简短了很多,而且这一版本拥有更多的功能:当电子邮件客户端不能处理HTML时,它将显示备用的文字。我们从创建一个SimpleEmail实例改变为创建一个HtmlEmail实例。为了嵌入一个图片,我们只需要简单地调用HtmlEmail的嵌入方法,这将返回一个字符串,该字符串含有被生成和管理的内嵌图片内容标识符的信息,我们可以直接使用这些信息来生成HTML内容。我们只需要简单地对适当的字符串调用setHtmlMsg方法来进行设定,setTextMsg将设定不支持HTML的客户端所显示的文字,然后我们就可以发送邮件了。

     但是,到目前为止,您可能正在想直接使用JavaMail的意义是什么呢?答案是,如果您的目的是发送电子邮件,那么对于大多数情况,通用电子邮件库仅仅需要少量的复杂代码就可以完成您的需求,但是它连一点控制邮件会话和接收邮件的功能都没有,如果您的应用软件不需要大规模地进行邮件转换或邮件阅读的操作,那么应该不会造成不便。当然,如果您需要进行上述操作,那您就已经在使用JavaMail库了。这里唯一的一个警告就是,在我写这篇文章之时,通用电子邮件库发布的是1.0版本,其API中可能有一些缺陷和漏洞,但它确实可以工作。现在您应该没有借口不让您的应用软件在工作的时候发送状态邮件了。

 

分享到:
评论

相关推荐

    JAVA上百实例源码以及开源项目

     Java编写的HTML浏览器源代码,一个很简单甚至不算是浏览器的HTML浏览器,使用方法:  可直接输入文件名或网络地址,但必需事先连入网络。 Java编写的山寨QQ,多人聊天+用户在线 21个目标文件 摘要:JAVA源码,...

    JAVA上百实例源码以及开源项目源代码

     Java编写的HTML浏览器源代码,一个很简单甚至不算是浏览器的HTML浏览器,使用方法:  可直接输入文件名或网络地址,但必需事先连入网络。 Java编写的山寨QQ,多人聊天+用户在线 21个目标文件 摘要:JAVA源码,...

    基于Java mail的邮件收发系统的毕业设计,该技术提供了一套用于发送、接收电子邮件的API,可以方便地实现邮件的发送和接收

    系统的设计采用了Javamail技术,该技术提供了一套用于发送、接收电子邮件的API,可以方便地实现邮件的发送和接收。同时,系统还采用了MySQL作为数据库,存储用户的邮件信息以及系统的配置信息。 在系统的实现过程中...

    java开源包8

    Java发送短信包 LemonSMS LemonSMS 这个Java库可以让开发者在应用程序中集成使用GSM调制解调器或兼容电话来发送SMS消息。 远程桌面 Java Remote Desktop.tar Java Remote Desktop 是一个Java 的远程桌面软件,支持...

    java开源包11

    Java发送短信包 LemonSMS LemonSMS 这个Java库可以让开发者在应用程序中集成使用GSM调制解调器或兼容电话来发送SMS消息。 远程桌面 Java Remote Desktop.tar Java Remote Desktop 是一个Java 的远程桌面软件,支持...

    java开源包6

    Java发送短信包 LemonSMS LemonSMS 这个Java库可以让开发者在应用程序中集成使用GSM调制解调器或兼容电话来发送SMS消息。 远程桌面 Java Remote Desktop.tar Java Remote Desktop 是一个Java 的远程桌面软件,支持...

    java开源包9

    Java发送短信包 LemonSMS LemonSMS 这个Java库可以让开发者在应用程序中集成使用GSM调制解调器或兼容电话来发送SMS消息。 远程桌面 Java Remote Desktop.tar Java Remote Desktop 是一个Java 的远程桌面软件,支持...

    java开源包4

    Java发送短信包 LemonSMS LemonSMS 这个Java库可以让开发者在应用程序中集成使用GSM调制解调器或兼容电话来发送SMS消息。 远程桌面 Java Remote Desktop.tar Java Remote Desktop 是一个Java 的远程桌面软件,支持...

    java开源包101

    Java发送短信包 LemonSMS LemonSMS 这个Java库可以让开发者在应用程序中集成使用GSM调制解调器或兼容电话来发送SMS消息。 远程桌面 Java Remote Desktop.tar Java Remote Desktop 是一个Java 的远程桌面软件,支持...

    java开源包5

    Java发送短信包 LemonSMS LemonSMS 这个Java库可以让开发者在应用程序中集成使用GSM调制解调器或兼容电话来发送SMS消息。 远程桌面 Java Remote Desktop.tar Java Remote Desktop 是一个Java 的远程桌面软件,支持...

    java开源包10

    Java发送短信包 LemonSMS LemonSMS 这个Java库可以让开发者在应用程序中集成使用GSM调制解调器或兼容电话来发送SMS消息。 远程桌面 Java Remote Desktop.tar Java Remote Desktop 是一个Java 的远程桌面软件,支持...

    java开源包3

    Java发送短信包 LemonSMS LemonSMS 这个Java库可以让开发者在应用程序中集成使用GSM调制解调器或兼容电话来发送SMS消息。 远程桌面 Java Remote Desktop.tar Java Remote Desktop 是一个Java 的远程桌面软件,支持...

    java开源包1

    Java发送短信包 LemonSMS LemonSMS 这个Java库可以让开发者在应用程序中集成使用GSM调制解调器或兼容电话来发送SMS消息。 远程桌面 Java Remote Desktop.tar Java Remote Desktop 是一个Java 的远程桌面软件,支持...

    电子邮件发送程序的设计与实现.doc

    1.2课程设计目的 本课程设计的目的主要是学习在VS平台下围绕着电子邮件发送的编程与开发,应用软 件工程的开发过程,详细论述了SMTP的分析、设计及代码实现,最终实现一个具有能发 送简单邮件,发送带附件的邮件的...

    JAVA 范例大全 光盘 资源

    实例71 配置Properties带附件发送邮件 175 实例72 资源国际化(Properties) 179 常见问题 读取Properties文件出现中文乱码 182 第9章 Java异常处理与反射机制 183 实例73 运用throws、throw、try与catch 183 ...

    java开源包2

    Java发送短信包 LemonSMS LemonSMS 这个Java库可以让开发者在应用程序中集成使用GSM调制解调器或兼容电话来发送SMS消息。 远程桌面 Java Remote Desktop.tar Java Remote Desktop 是一个Java 的远程桌面软件,支持...

    java开源包7

    Java发送短信包 LemonSMS LemonSMS 这个Java库可以让开发者在应用程序中集成使用GSM调制解调器或兼容电话来发送SMS消息。 远程桌面 Java Remote Desktop.tar Java Remote Desktop 是一个Java 的远程桌面软件,支持...

    Java资源包01

    Java发送短信包 LemonSMS LemonSMS 这个Java库可以让开发者在应用程序中集成使用GSM调制解调器或兼容电话来发送SMS消息。 远程桌面 Java Remote Desktop.tar Java Remote Desktop 是一个Java 的远程桌面软件,支持...

    其他类别MeyboMail Web(Java)开源简化-meybomailweb.zip

    MeyboMail Web(Java)是...总的来说,MeyboMail Web(Java)是一个功能强大、易于使用和学习的电子邮件系统,它为开发者提供了一个很好的实践平台,可以帮助他们深入理解电子邮件系统的工作原理和开发过程。重新回答||

Global site tag (gtag.js) - Google Analytics