分类: Java
2015-06-09 08:30:46
API 的核心类:Session、Message、Address、Authenticator、Transport、Store和 Folder。尽管自己使用的子类在 javax.mail.internet 中,但上述这些类却放在 JavaMail API的顶级包 javax.mail 里。
Session
类定义了一个基本邮件会话(session)。所有其它类都是经由这个session 才得以生效。Session对象用 对象获取信息,如邮件服务器、用户名、密码及整个应用程序中共享的其它信息。
类的构造器是私有的(private)。您可以得到单个缺省 session,它能用 getDefaultInstance() 方法被共享:
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.getDefaultInstance(props, null);
对于这两种情况,null参数都是 Authenticator 对象(在这次没有使用)。
对于大多数情况,共享的 session 已经够用了,即使要处理多个用户邮箱的邮件 session 也一样。您可以在通信过程中稍后的步骤加入用户名和密码组合,让一切保持独立。
Message
一旦获得 Session 对象,就可以继续创建要发送的消息。这由 类来完成。因为 Message 是个抽象类,您必需用一个子类,多数情况下为 。MimeMessage是个能理解 MIME 类型和头的电子邮件消息,正如不同 RFC 中所定义的。虽然在某些头部域非 ASCII 字符也能被译码,但 Message 头只能被限制为用 US-ASCII 字符。
要创建一个 Message,请将 Session 对象传递给 MimeMessage 构造器:
MimeMessage message = new MimeMessage(session);
注意:还存在其它构造器,如用按 RFC822 格式的输入流来创建消息。
一旦获得消息,您就可以设置各个部分,因为 Message 实现 接口(且 MimeMessage 实现 )。设置内容的基本机制是 setContent() 方法,同时使用参数,分别代表内容和 mime 类型:
message.setContent("Hello", "text/plain");
但如果,您知道您在使用 MimeMessage,而且消息是纯文本格式,您就可以用 setText() 方法,它只需要代表实际内容的参数,( MIME 类型缺省为 text/plain):
message.setText("Hello");
后一种格式是设置纯文本消息内容的首选机制。至于发送其它类型的消息,如 HTML 文件格式的消息,我们首选前者。
用 setSubject() 方法设置 subject(主题):
message.setSubject("First");
Address
一旦您创建了 Session 和 Message,并将内容填入消息后,就可以用 确定信件地址了。和 Message 一样,Address也是个抽象类。您用的是 类。
若创建的地址只包含电子邮件地址,只要传递电子邮件地址到构造器就行了。
Address address = new InternetAddress("president@whitehouse.gov");
若希望名字紧挨着电子邮件显示,也可以把它传递给构造器:
Address address = new InternetAddress("president@whitehouse.gov", "George Bush");
需要为消息的 from 域和 to 域创建地址对象。除非邮件服务器阻止,没什么能阻止你发送一段看上去是来自任何人的消息。
一旦创建了 address(地址),将它们与消息连接的方法有两种。如果要识别发件人,您可以用 setFrom() 和 setReplyTo() 方法。
message.setFrom(address)
需要消息显示多个 from 地址,可以使用 addFrom() 方法:
Address address[] = ...;
message.addFrom(address);
若要识别消息 recipient(收件人),您可以使用 addRecipient() 方法。除 address(地址)外,这一方法还请求一个 。
message.addRecipient(type, address)
三种预定义的地址类型是:
· Message.RecipientType.TO
· Message.RecipientType.CC
· Message.RecipientType.BCC
如果消息是发给副总统的,同时发送一个副本(carbon copy)给总统夫人,以下做法比较恰当:
Address toAddress = new InternetAddress("vice.president@whitehouse.gov");
Address ccAddress = new InternetAddress("first.lady@whitehouse.gov");
message.addRecipient(Message.RecipientType.TO, toAddress);
message.addRecipient(Message.RecipientType.CC, ccAddress);
JavaMail API 没有提供电子邮件地址有效性核查机制。虽然通过编程,自己能够扫描有效字符(如 RFC 822 中定义的)或验证邮件交换(mail exchange,MX)记录,但这些功能不属于 JavaMail API。
Authenticator
与 java.net 类一样,JavaMail API 也可以利用 通过用户名和密码访问受保护的资源。对于JavaMail API 来说,这些资源就是邮件服务器。JavaMail Authenticator 在 javax.mail 包中,而且它和 java.net 中同名的类 Authenticator 不同。两者并不共享同一个 Authenticator,因为JavaMail API 用于 Java 1.1,它没有 java.net 类别。
要使用 Authenticator,先创建一个抽象类的子类,并从 getPasswordAuthentication() 方法中返回 实例。创建完成后,您必需向 session 注册 Authenticator。然后,在需要认证的时候,就会通知 Authenticator。您可以弹出窗口,也可以从配置文件中(虽然没有加密是不安全的)读取用户名和密码,将它们作为 PasswordAuthentication 对象返回给调用程序。
Properties props = new Properties();
// fill props with any information
Authenticator auth = new MyAuthenticator();
Session session = Session.getDefaultInstance(props, auth);
Transport
消息发送的最后一部分是使用 类。这个类用协议指定的语言发送消息(通常是 SMTP)。它是抽象类,它的工作方式与 Session 有些类似。仅调用静态 send() 方法,就能使用类的缺省版本:
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();
后面这种方法在您要发送多条消息时最好,因为它能保持邮件服务器在消息间的活动状态。基本 send() 机制为每个方法的调用设置与服务器独立的连接。
注意:要观察传到邮件服务器上的邮件命令,请用 session.setDebug(true) 设置调试标志。
Store 和 Folder
用 Session 获取消息与发送消息开始很相似。但是,在 session 得到后,很可能使用用户名和密码或使用 Authenticator 连接到一个 。类似于 Transport ,您告知 Store 使用什么协议:
// Store store = session.getStore("imap");
Store store = session.getStore("pop3");
store.connect(host, username, password);
连接到 Store 之后,接下来,您就可以获取一个 ,您必需先打开它,然后才能读里面的消息。
Folder folder = store.getFolder("INBOX");
folder.open(Folder.READ_ONLY);
Message message[] = folder.getMessages();
POP3 唯一可以用的文件夹是 INBOX。如果使用 IMAP,还可以用其它文件夹。
注意:Sun 的供应商有意变得聪明。虽然 Message message[] = folder.getMessages(); 看上去是个很慢的操作,它从服务器上读取每一条消息,但仅在你实际需要消息的一部分时,消息的内容才会被检索。
一旦有了要读的 Message,您可以用 getContent() 来获取其内容,或者用 writeTo() 将内容写入流。getContent()方法只能得到消息内容,而 writeTo() 的输出却包含消息头。
System.out.println(((MimeMessage)message).getContent());
一旦读完邮件,要关闭与 folder 和 store 的连接。
folder.close(aBoolean);
store.close();
传递给 folder 的 close() 方法的 boolean 表示是否清除已删除的消息从而更新 folder。