五、如何使用JavaMail API
在明确了JavaMail API的核心部分如何工作后,本人将带领大家学习一些使用Java Mail API任务案例。
1.发送邮件
在获得了Session后,建立并填入邮件信息,然后发送它到邮件服务器。这便是使用Java Mail API发送邮件的过程,在发送邮件之前,我们需要设置SMTP服务器:通过设置Properties的mail.smtp.host属性。
复制String host = ...;String from = ...;
String to = ...;// Get system propertiesProperties props = System.getProperties();
// Setup mail serverprops.put("mail.smtp.host", host);
// Get sessionSession session = Session.getDefaultInstance(props, null);
// Define messageMimeMessage message = new MimeMessage(session);
message.setFrom(new InternetAddress(from));
message.addRecipient(Message.RecipientType.TO,
new InternetAddress(to));message.setSubject("Hello JavaMail");
message.setText("Welcome to JavaMail");
// Send messageTransport.send(message);
1.2.3.4.5.6.7.8.9.10.
由于建立邮件信息和发送邮件的过程中可能会抛出异常,所以我们需要将上面的代码放入到try-catch结构块中。
2.接收邮件
为了在读取邮件,我们获得了session,并且连接到了邮箱的相应store,打开相应的Folder,然后得到我们想要的邮件,当然别忘记了在结束时关闭连接。
复制String host = ...;String username = ...;
String password = ...;// Create empty propertiesProperties props = new Properties();
// Get sessionSession session = Session.getDefaultInstance(props, null);
// Get the storeStore store = session.getStore("pop3");
store.connect(host, username, password);
// Get folderFolder folder = store.getFolder("INBOX");
folder.open(Folder.READ_ONLY);
// Get directoryMessage message[] = folder.getMessages();
for (int i=0, n=message.length;
i": " + message[i].getFrom()[0]
+ "https://www.51cto.com/\t" + message[i].getSubject());}
// Close connection folder.close(false);
store.close();
1.2.3.4.5.6.7.8.9.10.11.12.13.
上面的代码所作的是从邮箱中读取每个邮件,并且显示邮件的发信人地址和主题。从技术角度讲,这里存在着一个异常的可能:当发信人地址为空时,getFrom()[0]将抛出异常。
下面的代码片断有效的说明了如何读取邮件内容,在显示每个邮件发信人和主题后,将出现用户提示从而得到用户是否读取该邮件的确认,如果输入YES的话,我们可用Message.writeTo(java.io.OutputStream os)方法将邮件内容输出到控制台上,关于Message.writeTo()的具体用法请看JavaMail API。
复制BufferedReader reader = new BufferedReader ( new InputStreamReader(System.in));
// Get directoryMessage message[] = folder.getMessages();
for (int i=0, n=message.length; i
{ System.out.println(i + ": " + message[i].getFrom()[0]
+ "https://www.51cto.com/\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); }
elseif ("QUIT".equals(line)) { break; }}
1.2.3.4.5.6.7.8.9.
3.删除邮件和标志
设置与message相关的Flags是删除邮件的常用方法。这些Flags表示了一些系统定义和用户定义的不同状态。在Flags类的内部类Flag中预定义了一些标志:
复制Flags.Flag.ANSWERED
Flags.Flag.DELETED
Flags.Flag.DRAFT
Flags.Flag.FLAGGED
Flags.Flag.RECENT
Flags.Flag.SEEN
Flags.Flag.USER
1.2.3.4.5.6.7.
但需要在使用时注意的:标志存在并非意味着这个标志被所有的邮件服务器所支持。例如,对于删除邮件的操作,POP协议不支持上面的任何一个。所以要确定哪些标志是被支持的——通过访问一个已经打开的Folder对象的getPermanetFlags()方法,它将返回当前被支持的Flags类对象。
删除邮件时,我们可以设置邮件的DELETED标志:
复制message.setFlag(Flags.Flag.DELETED, true);
但是首先要采用READ_WRITE的方式打开Folder:
folder.open(Folder.READ_WRITE);
1.2.3.
在对邮件进行删除操作后关闭Folder时,需要传递一个true作为对删除邮件的擦除确认。
folder.close(true);
Folder类中另一种用于删除邮件的方法expunge()也同样可删除邮件,但是它并不为sun提供的POP3实现支持,而其它第三方提供的POP3实现支持或者并不支持这种方法。
另外,介绍一种检查某个标志是否被设置的方法:Message.isSet(Flags.Flag flag)方法,其中参数为被检查的标志。
4.邮件认证
我们在前面已经学会了如何使用Authenticator类来代替直接使用用户名和密码这两字符串作为Session.getDefaultInstance()或者Session.getInstance()方法的参数。在前面的小试牛刀后,现在我们将了解到全面认识一下邮件认证。
我们在此取代了直接使用邮件服务器主机名、用户名、密码这三个字符串作为连接到POP3 Store的方式,使用存储了邮件服务器主机名信息的属性文件,并在获得Session时传入自定义的Authenticator实例:
复制// Setup propertiesProperties props = System.getProperties();
props.put("mail.pop3.host", host);
// Setup authentication, get sessionAuthenticator auth = new PopupAuthenticator();
Session session = Session.getDefaultInstance(props, auth);
// Get the storeStore store = session.getStore("pop3");
store.connect();
1.2.3.4.5.6.
PopupAuthenticator类继承了抽象类Authenticator,并且通过重载Authenticator类的getPasswordAuthentication()方法返回PasswordAuthentication类对象。而getPasswordAuthentication()方法的参数param是以逗号分割的用户名、密码组成的字符串。
复制import javax.mail.*;
import java.util.*;
publicclass PopupAuthenticator extends Authenticator
{ public PasswordAuthentication getPasswordAuthentication(String param)
{ String username, password;
StringTokenizer st = new StringTokenizer(param, ",");
username = st.nextToken();
password = st.nextToken();
returnnew PasswordAuthentication(username, password); }}
1.2.3.4.5.6.7.8.9.
5.回复邮件
回复邮件的方法很简单:使用Message类的reply()方法,通过配置回复邮件的收件人地址和主题(如果没有提供主题的话,系统将默认将“Re:”作为邮件的主体),这里不需要设置任何的邮件内容,只要复制发信人或者reply-to到新的收件人。而reply()方法中的boolean参数表示是否将邮件回复给发送者(参数值为false),或是恢复给所有人(参数值为true)。
补充一下,reply-to地址需要在发信时使用setReplyTo()方法设置。
复制MimeMessage reply = (MimeMessage)message.reply(false);
reply.setFrom(new InternetAddress("president@whitehouse.gov"));
reply.setText("Thanks");
Transport.send(reply);
1.2.3.4.
6.转发邮件
转发邮件的过程不如前面的回复邮件那样简单,它将建立一个转发邮件,这并非一个方法就能做到。
每个邮件是由多个部分组成,每个部分称为一个邮件体部分,是一个BodyPart类对象,对于MIME类型邮件来讲就是MimeBodyPart类对象。这些邮件体包含在成为Multipart的容器中对于MIME类型邮件来讲就是MimeMultiPart类对象。在转发邮件时,我们建立一个文字邮件体部分和一个被转发的文字邮件体部分,然后将这两个邮件体放到一个Multipart中。说明一下,复制一个邮件内容到另一个邮件的方法是仅复制它的DataHandler(数据处理者)即可。这是由JavaBeans Activation Framework定义的一个类,它提供了对邮件内容的操作命令的访问、管理了邮件内容操作,是不同的数据源和数据格式之间的一致性接口。
复制// Create the message to forwardMessage forward = new MimeMessage(session);
// Fill in headerforward.setSubject("Fwd: " + message.getSubject());
forward.setFrom(new InternetAddress(from));
forward.addRecipient(Message.RecipientType.TO, new InternetAddress(to));
// Create your new message partBodyPart messageBodyPart = new MimeBodyPart();messageBodyPart.setText
( "Here you go with the original message:https://www.51cto.com/\nhttps://www.51cto.com/\n");
// Create a multi-part to combine the partsMultipart multipart = new MimeMultipart();
multipart.addBodyPart(messageBodyPart);
// Create and fill part for the forwarded contentmessageBodyPart = new MimeBodyPart();
messageBodyPart.setDataHandler(message.getDataHandler());
// Add part to multi partmultipart.addBodyPart(messageBodyPart);
// Associate multi-part with messageforward.setContent(multipart);
// Send messageTransport.send(forward);
1.2.3.4.5.6.7.8.9.10.11.12.13.
7.使用附件
附件作为与邮件相关的资源经常以文本、表格、图片等格式出现,如流行的邮件客户端一样,我们可以用JavaMail API从邮件中获取附件或是发送带有附件的邮件。
A.发送带有附件的邮件
发送带有附件的邮件的过程有些类似转发邮件,我们需要建立一个完整邮件的各个邮件体部分,在第一个部分(即我们的邮件内容文字)后,增加一个具有DataHandler的附件而不是在转发邮件时那样复制第一个部分的DataHandler。
如果我们将文件作为附件发送,那么要建立FileDataSource类型的对象作为附件数据源;如果从URL读取数据作为附件发送,那么将要建立URLDataSource类型的对象作为附件数据源。
然后将这个数据源(FileDataSource或是URLDataSource)对象作为DataHandler类构造方法的参数传入,从而建立一个DataHandler对象作为数据源的DataHandler。
接着将这个DataHandler设置为邮件体部分的DataHandler。这样就完成了邮件体与附件之间的关联工作,下面的工作就是BodyPart的setFileName()方法设置附件名为原文件名。
最后将两个邮件体放入到Multipart中,设置邮件内容为这个容器Multipart,发送邮件。
复制// Define messageMessage message = new MimeMessage(session);
message.setFrom(new InternetAddress(from));
message.addRecipient(Message.RecipientType.TO,
new InternetAddress(to));message.setSubject("Hello JavaMail Attachment");
// Create the message part BodyPart messageBodyPart = new MimeBodyPart();
// Fill the messagemessageBodyPart.setText("Pardon Ideas");
Multipart multipart = new MimeMultipart();
multipart.addBodyPart(messageBodyPart);
// Part two is attachmentmessageBodyPart = new MimeBodyPart();
DataSource source = new FileDataSource(filename);
messageBodyPart.setDataHandler(new DataHandler(source));
messageBodyPart.setFileName(filename);multipart.addBodyPart(messageBodyPart);
// Put parts in messagemessage.setContent(multipart);
// Send the messageTransport.send(message);
1.2.3.4.5.6.7.8.9.10.11.12.13.14.
如果我们使用servlet实现发送带有附件的邮件,则必须上传附件给servlet,这时需要注意提交页面form中对编码类型的设置应为multipart/form-data。
暂时没有评论,来抢沙发吧~