版权声明:本文可以自由转载,转载时请务必以超链接形式标明文章原始出处和作者信息及本声明
作者:cleverpig(作者的blog:http://blog.matrix.org.cn/page/cleverpig)
原文:http://www.matrix.org.cn/resource/article/44/44101_javamail.html
关键字:java,mail,pop,smtp
一、javamail api简介
javamail api是读取、撰写、发送电子信息的可选包。我们可用它来建立如eudora、foxmail、ms outlook express一般的邮件用户代理程序(mail user agent,简称mua)。而不是像sendmail或者其它的邮件传输代理(mail transfer agent,简称mta)程序那样可以传送、递送、转发邮件。从另外一个角度来看,我们这些电子邮件用户日常用mua程序来读写邮件,而mua依赖着mta处理邮件的递送。
在清楚了到mua与mta之间的关系后,让我们看看javamail api是如何提供信息访问功能的吧!javamail api被设计用于以不依赖协议的方式去发送和接收电子信息,这个api被分为两大部分:
基本功能:如何以不依赖于协议的方式发送接收电子信息,这也是本文所要描述的,不过在下文中,大家将看到这只是一厢情愿而已。
第二个部分则是依赖特定协议的,比如smtp、pop、imap、nntp协议。在这部分的javamail api是为了和服务器通讯,并不在本文的内容中。
二、相关协议一览
在我们步入javamail api之前,先看一下api所涉及的协议。以下便是大家日常所知、所乐于使用的4大信息传输协议:
smtp
pop
imap
mime
当然,上面的4个协议,并不是全部,还有nntp和其它一些协议可用于传输信息,但是由于不常用到,所以本文便不提及了。理解这4个基本的协议有助于我们更好的使用javamail api。然而javamail api是被设计为与协议无关的,目前我们并不能克服这些协议的束缚。确切的说,如果我们使用的功能并不被我们选择的协议支持,那么javamail api并不可能如魔术师一样神奇的赋予我们这种能力。
1.smtp
简单邮件传输协议定义了递送邮件的机制。在下文中,我们将使用基于java-mail的程序与公司或者isp的smtp服务器进行通讯。这个smtp服务器将邮件转发到接收者的smtp服务器,直至最后被接收者通过pop或者imap协议获取。这并不需要smtp服务器使用支持授权的邮件转发,但是却的确要注意smtp服务器的正确设置(smtp服务器的设置与javamail api无关)。
2.pop
pop是一种邮局协议,目前为第3个版本,即众所周知的pop3。pop定义了一种用户如何获得邮件的机制。它规定了每个用户使用一个单独的邮箱。大多数人在使用pop时所熟悉的功能并非都被支持,例如查看邮箱中的新邮件数量。而这个功能是微软的outlook内建的,那么就说明微软outlook之类的邮件客户端软件是通过查询最近收到的邮件来计算新邮件的数量来实现前面所说的功能。因此在我们使用javamail api时需要注意,当需要获得如前面所讲的新邮件数量之类的信息时,我们不得不自己进行计算。
3.imap
imap使用在接收信息的高级协议,目前版本为第4版,所以也被称为imap4。需要注意的是在使用imap时,邮件服务器必须支持该协议。从这个方面讲,我们并不能完全使用imap来替代pop,不能期待imap在任何地方都被支持。假如邮件服务器支持imap,那么我们的邮件程序将能够具有以下被imap所支持的特性:每个用户在服务器上可具有多个目录,这些目录能在多个用户之间共享。
其与pop相比高级之处显而易见,但是在尝试采取imap时,我们认识到它并不是十分完美的:由于imap需要从其它服务器上接收新信息,将这些信息递送给用户,维护每个用户的多个目录,这都为邮件服务器带来了高负载。并且imap与pop的一个不同之处是pop用户在接收邮件时将从邮件服务器上下载邮件,而imap允许用户直接访问邮件目录,所以在邮件服务器进行备份作业时,由于每个长期使用此邮件系统的用户所用的邮件目录会占有很大的空间,这将直接导致邮件服务器上磁盘空间暴涨。
4.mime
mime并不是用于传送邮件的协议,它作为多用途邮件的扩展定义了邮件内容的格式:信息格式、附件格式等等。一些rfc标准都涉及了mime:rfc 822, rfc 2045, rfc 2046, rfc 2047,有兴趣的matrixer可以阅读一下。而作为javamail api的开发者,我们并不需关心这些格式定义,但是这些格式被用在了程序中。
5.nntp和其它的第三方协议
正因为javamail api在设计时考虑到与第三方协议实现提供商之间的分离,故我们可以很容易的添加一些第三方协议。sun维护着一个第三方协议实现提供商的列表:http://java.sun.com/products/javamail/third_party.html,通过此列表我们可以找到所需要的而又不被sun提供支持的第三方协议:比如nntp这个新闻组协议和s/mime这个安全的mime协议。
三、安装
1.安装javamail
为了使用javamail api,需要从http://java.sun.com/products/javamail/downloads/index.html下载文件名格式为javamail-[version].zip的文件(这个文件中包括了javamail实现),并将其中的mail.jar文件添加到classpath中。这个实现提供了对smtp、imap4、pop3的支持。
注意:在安装javamail实现之后,我们将在demo目录中发现许多有趣的简单实例程序。
在安装了javamail之后,我们还需要安装javabeans activation framework,因为这个框架是javamail api所需要的。如果我们使用j2ee的话,那么我们并无需单独下载javamail,因为它存在于j2ee.jar中,只需将j2ee.jar加入到classpath即可。
2.安装javabeans activation framework
从http://java.sun.com/products/javabeans/glasgow/jaf.html下载javabeans activation framework,并将其添加到classpath中。此框架增加了对任何数据块的分类、以及对它们的处理的特性。这些特性是javamail api需要的。虽然听起来这些特性非常模糊,但是它对于我们的javamail api来说只是提供了基本的mime类型支持。
到此为止,我们应当把mail.jar和activation.jar都添加到了classpath中。
当然如果从方便的角度讲,直接把这两个jar文件复制到jre目录的lib/ext目录中也可以。
四、初次认识javamail api
1.了解我们的javamail环境
a.纵览javamail核心类结构
打开javamail.jar文件,我们将发现在javax.mail的包下面存在着一些核心类:session、message、address、authenticator、transport、store、folder。而且在javax.mail.inte.net包中还有一些常用的子类。
b.session
session类定义了基本的邮件会话。就像http会话那样,我们进行收发邮件的工作都是基于这个会话的。session对象利用了java.util.properties对象获得了邮件服务器、用户名、密码信息和整个应用程序都要使用到的共享信息。
session类的构造方法是私有的,所以我们可以使用session类提供的getdefaultinstance()这个静态工厂方法获得一个默认的session对象:
properties props = new properties();
// fill props with any information
session session = session.getdefaultinstance(props, null);
properties props = new properties();
// fill props with any information
session session = session.getinstance(props, null);
mimemessage message = new mimemessage(session);
message.setcontent("hello", "text/plain");
message.settext("hello");
message.setsubject("first");
address address = new inte.netaddress("president@whitehouse.gov");
address address = new inte.netaddress("president@whitehouse.gov", "george bush");
message.setfrom(address);
message.setreplyto(address);
address address[] = ...;
message.addfrom(address);
message.addrecipient(type, address)
address toaddress = new inte.netaddress("vice.president@whitehouse.gov");
address ccaddress = new inte.netaddress("first.lady@whitehouse.gov");
message.addrecipient(message.recipienttype.to, toaddress);
message.addrecipient(message.recipienttype.cc, ccaddress);
properties props = new properties();
// fill props with any information
authenticator auth = new myauthenticator();
session session = session.getdefaultinstance(props, auth);
transport.send(message);
message.savechanges(); // implicit with send()
transport transport = session.gettransport("smtp");
transport.connect(host, username, password);
transport.sendmessage(message, message.getallrecipients());
transport.close();
session.setdebug(true)。
// store store = session.getstore("imap");
store store = session.getstore("pop3");
store.connect(host, username, password);
folder folder = store.getfolder("inbox");
folder.open(folder.read_only);
message message[] = folder.getmessages();
system.out.println(((mimemessage)message).getcontent());
folder.close(aboolean);
store.close();
string host = ...;
string from = ...;
string to = ...;
// get system properties
properties props = system.getproperties();
// setup mail server
props.put("mail.smtp.host", host);
// get session
session session = session.getdefaultinstance(props, null);
// define message
mimemessage message = new mimemessage(session);
message.setfrom(new inte.netaddress(from));
message.addrecipient(message.recipienttype.to,
new inte.netaddress(to));
message.setsubject("hello javamail");
message.settext("welcome to javamail");
// send message
transport.send(message);
string host = ...;
string username = ...;
string password = ...;
// create empty properties
properties props = new properties();
// get session
session session = session.getdefaultinstance(props, null);
// get the store
store store = session.getstore("pop3");
store.connect(host, username, password);
// get folder
folder folder = store.getfolder("inbox");
folder.open(folder.read_only);
// get directory
message message[] = folder.getmessages();
for (int i=0, n=message.length; i<n; i++) {
system.out.println(i + ": " + message[i].getfrom()[0]
+ "\t" + message[i].getsubject());
}
// close connection
folder.close(false);
store.close();
bufferedreader reader = new bufferedreader (
new inputstreamreader(system.in));
// get directory
message message[] = folder.getmessages();
for (int i=0, n=message.length; i<n; i++) {
system.out.println(i + ": " + message[i].getfrom()[0]
+ "\t" + message[i].getsubject());
system.out.println("do you want to read message? " +
"[yes to read/quit to end]");
string line = reader.readline();
if ("yes".equals(line)) {
message[i].writeto(system.out);
} else if ("quit".equals(line)) {
break;
}
}
message.setflag(flags.flag.deleted, true);
folder.open(folder.read_write);
folder.close(true);
// setup properties
properties props = system.getproperties();
props.put("mail.pop3.host", host);
// setup authentication, get session
authenticator auth = new popupauthenticator();
session session = session.getdefaultinstance(props, auth);
// get the store
store store = session.getstore("pop3");
store.connect();
import javax.mail.*;
import java.util.*;
public class popupauthenticator extends authenticator {
public passwordauthentication getpasswordauthentication(string param) {
string username, password;
stringtokenizer st = new stringtokenizer(param, ",");
username = st.nexttoken();
password = st.nexttoken();
return new passwordauthentication(username, password);
}
}
mimemessage reply = (mimemessage)message.reply(false);
reply.setfrom(new inte.netaddress("president@whitehouse.gov"));
reply.settext("thanks");
transport.send(reply);
// create the message to forward
message forward = new mimemessage(session);
// fill in header
forward.setsubject("fwd: " + message.getsubject());
forward.setfrom(new inte.netaddress(from));
forward.addrecipient(message.recipienttype.to,
new inte.netaddress(to));
// create your new message part
bodypart messagebodypart = new mimebodypart();
messagebodypart.settext(
"here you go with the original message:\n\n");
// create a multi-part to combine the parts
multipart multipart = new mimemultipart();
multipart.addbodypart(messagebodypart);
// create and fill part for the forwarded content
messagebodypart = new mimebodypart();
messagebodypart.setdatahandler(message.getdatahandler());
// add part to multi part
multipart.addbodypart(messagebodypart);
// associate multi-part with message
forward.setcontent(multipart);
// send message
transport.send(forward);
// define message
message message = new mimemessage(session);
message.setfrom(new inte.netaddress(from));
message.addrecipient(message.recipienttype.to,
new inte.netaddress(to));
message.setsubject("hello javamail attachment");
// create the message part
bodypart messagebodypart = new mimebodypart();
// fill the message
messagebodypart.settext("pardon ideas");
multipart multipart = new mimemultipart();
multipart.addbodypart(messagebodypart);
// part two is attachment
messagebodypart = new mimebodypart();
datasource source = new filedatasource(filename);
messagebodypart.setdatahandler(new datahandler(source));
messagebodypart.setfilename(filename);
multipart.addbodypart(messagebodypart);
// put parts in message
message.setcontent(multipart);
// send the message
transport.send(message);
<form enctype="multipart/form-data"
method=post action="/myservlet">
<input type="file" name="thefile">
<input type="submit" value="upload">
</form>
multipart mp = (multipart)message.getcontent();
for (int i=0, n=multipart.getcount(); i<n; i++) {
part part = multipart.getbodypart(i));
string disposition = part.getdisposition();
if ((disposition != null) &&
((disposition.equals(part.attachment)
(disposition.equals(part.inline))) {
savefile(part.getfilename(), part.getinputstream());
}
}
// from savefile()
file file = new file(filename);
for (int i=0; file.exists(); i++) {
file = new file(filename+i);
}
if (disposition == null) {
// check if plain
mimebodypart mbp = (mimebodypart)part;
if (mbp.ismimetype("text/plain")) {
// handle plain
} else {
// special non-attachment cases here of
// image/gif, text/html, ...
}
...
}
string htmltext = "<h1>hello</h1>" +
"<img src=\"http://www.jguru.com/images/logo.gif\">";
message.setcontent(htmltext, "text/html"));
if (message.getcontenttype().equals("text/html")) {
string content = (string)message.getcontent();
jframe frame = new jframe();
jeditorpane text = new jeditorpane("text/html", content);
text.seteditable(false);
jscrollpane pane = new jscrollpane(text);
frame.getcontentpane().add(pane);
frame.setsize(300, 300);
frame.setdefaultcloseoperation(jframe.dispose_on_close);
frame.show();
}
string file = ...;
// create the message
message message = new mimemessage(session);
// fill its headers
message.setsubject("embedded image");
message.setfrom(new inte.netaddress(from));
message.addrecipient(message.recipienttype.to,
new inte.netaddress(to));
// create your new message part
bodypart messagebodypart = new mimebodypart();
string htmltext = "<h1>hello</h1>" +
"<img src=\"cid:memememe\">";
messagebodypart.setcontent(htmltext, "text/html");
// create a related multi-part to combine the parts
mimemultipart multipart = new mimemultipart("related");
multipart.addbodypart(messagebodypart);
// create part for the image
messagebodypart = new mimebodypart();
// fetch the image and associate to part
datasource fds = new filedatasource(file);
messagebodypart.setdatahandler(new datahandler(fds));
messagebodypart.setheader("content-id","<memememe>");
// add part to multi-part
multipart.addbodypart(messagebodypart);
// associate multi-part with message
message.setcontent(multipart);
searchterm st = ...;
message[] msgs = folder.search(st);
searchterm st =
new orterm(
new subjectterm("adv:"),
new fromstringterm("friend@public.com"));
message[] msgs = folder.search(st);
Java Asp PHP .Net XML C/C++ CGI VB Jsp J2ee J2se J2me EJB Servlet Tomcat Resin Struts Weblogic Eclipse ANT GUI JMS Web servise IDEA Webphere Hibernate Spring Jboss Applet Swing Socket Javamail Perl Ajax P2P 安全 模式 框架 测试 开源 游戏
Windows XP Windows 2000 Windows 2003 Windows Me Windows 9.x Linux UNIX 注册表 操作系统 服务器 应用服务器