JavaMail 手册篇

这篇博客详细介绍了JavaMail API,包括SMTP、POP、IMAP和MIME等邮件协议,以及JavaMail API的核心类如Session、Message、Address、Authenticator、Transport、Store和Folder的使用方法。通过示例展示了如何创建和发送邮件,以及如何接收和处理邮件。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

 1.协议一览
SMTP
  简单邮件传输协议(SMTP)是用于传送电子邮件的机制。在JavaMail API环境中,基于JavaMail的程序将与公司或Internet服务提供商(ISP)的SMTP服务器通信。该SMTP服务器将会把消息转发给用作接收消息的SMTP服务器,最后用户可通过POP或IMAP协议获取该消息。由于支持身份验证,所以不需要SMTP服务器是一种开放的转发器,但需要确保SMTP服务器配置正确。JavaMail API中没有集成用于处理诸如配置服务器以转发消息或添加/删除电子邮件帐户这一类任务的功能。
  
POP
  POP的含义是邮局协议,当前的版本为3,也称作POP3,该协议是在RFC 1939中定义的。POP是Internet上的大多数人用来接收邮件的机制。它为每个用户的每个邮箱定义支持,这是它所做的全部工作,也是大多数问题的根源。在使用POP协议时,人们熟悉的很多功能,如查看收到了多少新邮件消息的功能,POP根本不支持。这些功能都内置到诸如Eudora或Microsoft Outlook之类的邮件程序中,能为您记住接收的上一封邮件,以及计算有多少新邮件这类信息。因此,使用JavaMail API时,如果想获取这类信息,将需要由自己进行计算。

IMAP
  IMAP是用于接收消息的更加高级的协议,它是在RFC 2060中定义的。IMAP的含义是“Internet消息访问协议”,当前版本是第4版,也称作IMAP4。使用IMAP时,您的邮件服务器必须支持该协议。您不能只是简单地把程序转变为支持IMAP,而不是支持POP,就指望能支持IMAP中的一切。假定您的邮件服务器支持IMAP,那么基于JavaMail的程序就可利用在服务器上拥有多个文件夹的用户,并且这些文件夹可以被多个用户共享的功能。
  由于IMAP协议具有更高级的功能,您也许会想IMAP应该被每一个人使用,但事实不是这样。因为IMAP会加重邮件服务器的负荷,它需要服务器接收新消息,发送消息给请求的用户,并在多个文件夹中为每个用户维护这些消息。而这要集中备份,因而长期下去用户的文件夹会变得越来越大,当磁盘空间用光了时,每个人都会遭受损失。而使用POP协议时,已保存消息可以解除服务器的重负。
  
MIME
  MIME的含义是“多用途的网际邮件扩充协议”。它不是一种邮件传输协议,相反,它定义传输的内容:消息的格式、附件等。许多文档都定义了MIME协议,包含:RFC 822、RFC 2045、RFC 2046和RFC 2047。作为JavaMail API的用户,一般不需要担心这些格式。但是,这些格式确实存在,并为您的程序所用。
  
NNP和其他协议
  由于JavaMail API分开了提供程序和其他部分,所以您可以轻松地为附加协议添加支持。Sun公司提供第3方提供程序清单,这些提供程序要利用 Sun公司不支持的少见的协议。在这份清单中,您将会看到对NNTP(网络新闻传输协议)[新闻组]、S/MIME(安全多用途的网际邮件扩充协议)及其他协议的提供支持的第3方提供程序。

*********************************************************************************************************************************************

2.JavaMail API
    JavaMail API的核心类:会话消息地址验证程序传输存储文件夹。所有这些类都可以在JavaMail API即javax.mail的顶层包中找到,尽管你将频繁地发现你自己使用的子类是在javax.mail.internet包中找到的。

A.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);

---------------------------------------------------------------------------------------------
或者使用getInstance()这个静态工厂方法获得自定义的Session:
Properties props = new Properties();
// fill props with any information
Session session = Session.getInstance(props, null);
    getDefaultInstance()和getInstance()方法的第二个参数都是null,这是因为在上面的例子中并没有使用到邮件授权,下文中将对授权进行详细介绍。从很多的实例看,在对mail server进行访问的过程中使用共享的Session是足够的,即使是工作在多个用户邮箱的模式下也不例外。

B.Message
    当我们建立了Session对象后,便可以被发送的构造信息体了。在这里SUN提供了Message类型来帮助开发者完成这项工作。由于Message是一个抽象类,大多数情况下,我们使用javax.mail.internet.MimeMessage这个子类,该类是使用MIME类型、MIME信息头的邮箱信息。信息头只能使用US-ASCII字符,而非ASCII字符将通过编码转换为ASCII的方式使用。
为了建立一个MimeMessage对象,我们必须将Session对象作为MimeMessage构造方法的参数传入:
MimeMessage message = new MimeMessage(session);  
注意:对于MimeMessage类来讲存在着多种构造方法,比如使用输入流作为参数的构造方法。
在建立了MimeMessage对象后,我们需要设置它的各个part,对于MimeMessage类来说,这些part就是MimePart接口。
使用setSubject()方法对邮件设置邮件主题:
message.setSubject("Title");
基本的设置信息内容的方法就是通过表示信息内容和MIME类型的参数调用setContent()方法:
message.setContent("Hello", "text/plain");  
然而,如果我们所使用的MimeMessage中信息内容是文本的话,我们便可以直接使用setText()方法来方便的设置文本内容。
message.setText("Hello");  
前面所讲的两种方法,对于文本信息,后者更为合适。而对于其它的一些信息类型,比如HTML信息,则要使用前者。

C.Address
    至此,已经建立了Session和Message,下面将介绍如何使用邮件地址类:Address。像Message一样,Address类也是一个抽象类,所以我们将使用javax.mail.internet.InternetAddress这个子类。
通过传入代表邮件地址的字符串,我们可以建立一个邮件地址类:
Address address = new InternetAddress("xx@xxx.com");  
如果要在邮件地址后面增加名字的话,可以通过传递两个参数:代表邮件地址和名字的字符串来建立一个具有邮件地址和名字的邮件地址类:
Address address = new InternetAddress("xx@xxx.com", "Alvin");
本文在这里所讲的邮件地址类是为了设置邮件信息的发信人收信人而准备的,在建立了邮件地址类后,我们通过message的setFrom()和setReplyTo()两种方法设置邮件的发信人:
message.setFrom(address);
message.setReplyTo(address);  
若在邮件中存在多个发信人地址,我们可用addForm()方法增加发信人:
Address address[] = ...;
message.addFrom(address);
为了设置收信人,我们使用addRecipient()方法增加收信人,此方法需要使用Message.RecipientType的常量来区分收信人的类型:
message.addRecipient(type, address);
下面是Message.RecipientType的三个常量:
Message.RecipientType.TO
Message.RecipientType.CC
Message.RecipientType.BCC
因此,如果我们要发送邮件给A,并发用一个副本给B,下面的方法将被用到:
Address toAddress = new InternetAddress("A@xxx.com");
Address ccAddress = new InternetAddress("B@xxx.com");
message.addRecipient(Message.RecipientType.TO, toAddress);
message.addRecipient(Message.RecipientType.CC, ccAddress);
  
JavaMail API并没有提供检查邮件地址有效性的机制。当然我们可以自己完成这个功能:验证邮件地址的字符是否按照RFC822规定的格式书写或者通过DNS服务器上的MX记录验证等。

E.Authenticator
    像java.net类那样,JavaMail API通过使用授权者类(Authenticator)以用户名、密码的方式访问那些受到保护的资源,在这里“资源”就是指邮件服务器。在javax.mail包中可以找到这个JavaMail的授权者类(Authenticator)。
在使用Authenticator这个抽象类时,我们必须采用继承该抽象类的方式,并且该继承类必须具有返回PasswordAuthentication对象(用于存储认证时要用到的用户名、密码)getPasswordAuthentication()方法。并且要在Session中进行注册,使Session能够了解在认证时该使用哪个类。
下面代码片断中的MyAuthenticator就是一个Authenticator的子类。
Properties props = new Properties();
// fill props with any information
Authenticator auth = new MyAuthenticator();
Session session = Session.getDefaultInstance(props, auth);

F.Transport
    在发送信息时,Transport类将被用到。这个类实现了发送信息的协议(通称为SMTP),此类是一个抽象类,我们可以使用这个类的静态方法send()来发送消息:
Transport.send(message);  
当然,方法是多样的。我们也可由Session获得相应协议对应的Transport实例。并通过传递用户名、密码、邮件服务器主机名等参数建立与邮件服务器的连接,并使用sendMessage()方法将信息发送,最后关闭连接:
message.saveChanges();
// implicit with send()
Transport transport = session.getTransport("smtp");
transport.connect(host, username, password);
transport.sendMessage(message, message.getAllRecipients());
transport.close();  
评论:上面的方法是一个很好的方法,尤其是在我们在同一个邮件服务器上发送多个邮件时。因为这时我们将在连接邮件服务器后连续发送邮件,然后再关闭掉连接。send()这个基本的方法是在每次调用时进行与邮件服务器的连接的,对于在同一个邮件服务器上发送多个邮件来讲可谓低效的方式。
注意:如果需要在发送邮件过程中监控mail命令的话,可以在发送前设置debug标志:session.setDebug(true)。

G.Store和Folder
    接收邮件和发送邮件很类似都要用到Session。但是在获得Session后,我们需要从Session中获取特定类型的Store,然后连接到Store,这里的Store代表了存储邮件的邮件服务器。在连接Store的过程中,极有可能需要用到用户名、密码或者Authenticator。
// Store store = session.getStore("imap");
Store store = session.getStore("pop3");
store.connect(host, username, password);  
在连接到Store后,一个Folder对象即目录对象将通过Store的getFolder()方法被返回,我们可从这个Folder中读取邮件信息:
Folder folder = store.getFolder("INBOX");
folder.open(Folder.READ_ONLY);
Message message[] = folder.getMessages();

上面的例子首先从Store中获得INBOX这个Folder(对于POP3协议只有一个名为INBOX的Folder有效),然后以只读(Folder.READ_ONLY)的方式打开Folder,最后调用Folder的getMessages()方法得到目录中所有Message的数组。
注意:对于POP3协议只有一个名为INBOX的Folder有效,而对于IMAP协议,我们可以访问多个Folder(想想前面讲的IMAP协议)。而且SUN在设计Folder的getMessages()方法时采取了很智能的方式:首先接收新邮件列表,然后再需要的时候(比如读取邮件内容)才从邮件服务器读取邮件内容。
在读取邮件时,我们可以用Message类的getContent()方法接收邮件或是writeTo()方法将邮件保存,getContent()方法只接收邮件内容(不包含邮件头),而writeTo()方法将包括邮件头。
System.out.println(((MimeMessage)message).getContent());  
在读取邮件内容后,别忘记了关闭Folder和Store。
folder.close(aBoolean);
store.close();  
传递给Folder.close()方法的boolean 类型参数表示是否在删除操作邮件后更新Folder。

注:下文中的 *** 代表文件名中的组件名称。 # 包含: 中文-英文对照文档:【***-javadoc-API文档-中文(简体)-英语-对照版.zip】 jar包下载地址:【***.jar下载地址(官方地址+国内镜像地址).txt】 Maven依赖:【***.jar Maven依赖信息(可用于项目pom.xml).txt】 Gradle依赖:【***.jar Gradle依赖信息(可用于项目build.gradle).txt】 源代码下载地址:【***-sources.jar下载地址(官方地址+国内镜像地址).txt】 # 本文件关键字: 中文-英文对照文档,中英对照文档,java,jar包,Maven,第三方jar包,组件,开源组件,第三方组件,Gradle,中文API文档,手册,开发手册,使用手册,参考手册 # 使用方法: 解压 【***.jar中文文档.zip】,再解压其中的 【***-javadoc-API文档-中文(简体)版.zip】,双击 【index.html】 文件,即可用浏览器打开、进行查看。 # 特殊说明: ·本文档为人性化翻译,精心制作,请放心使用。 ·本文档为双语同时展示,一行原文、一行译文,可逐行对照,避免了原文/译文来回切换的麻烦; ·有原文可参照,不再担心翻译偏差误导; ·边学技术、边学英语。 ·只翻译了该翻译的内容,如:注释、说明、描述、用法讲解 等; ·不该翻译的内容保持原样,如:类名、方法名、包名、类型、关键字、代码 等。 # 温馨提示: (1)为了防止解压后路径太长导致浏览器无法打开,推荐在解压时选择“解压到当前文件夹”(放心,自带文件夹,文件不会散落一地); (2)有时,一套Java组件会有多个jar,所以在下载前,请仔细阅读本描述,以确保这就是你需要的文件;
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值