綜述:Java Mail API的開(kāi)發(fā)是SUN為Java開(kāi)發(fā)者提供公用API框架的持續努力的良好例證。提倡公用框架,反對受限于供應商的解決方案,充分預示著(zhù)一個(gè)日益開(kāi)放的開(kāi)發(fā)環(huán)境的建立。
Java Mail API的結構本身證明了它的開(kāi)發(fā)者的基本目標之一--軟件開(kāi)發(fā)的工作量應該取決于應用程序本身的復雜程度以及開(kāi)發(fā)者所要求的控制程度。換句話(huà)說(shuō),Java Mail API盡可能地保持簡(jiǎn)單。乍看起來(lái),Java Mail API所擁有的類(lèi)總數以及類(lèi)之間的關(guān)系可能讓人誤解為要花費漫長(cháng)的學(xué)習時(shí)間。實(shí)際上,一旦正式開(kāi)始使用,你就會(huì )發(fā)現該API不失為在應用程序中加入健壯的郵件/通訊支持的簡(jiǎn)單工具。
建立JavaMail使用環(huán)境,需要哪些軟件
首先,需要安裝JavaMail API?,F在有兩種常用的 JavaMail API 版本:1.2 和 1.1.3。雖然版本 1.2 是最新版,但版本 1.1.3 包含了Java 2 平臺企業(yè)版(Java 2 Platform, Enterprise Edition,J2EE)的版本 1.2.1,所以仍然有很多人使用它。
·JavaMail 1.2 的安裝
要使用 JavaMail 1.2 API,請下載 JavaMail 1.2 實(shí)現,解開(kāi)Javamail-1_2.zip 文件,并將 mail.jar 文件添加到 CLASSPATH 中。除了核心類(lèi),隨版本 1.2 實(shí)現一起提供的還有 SMTP、IMAP4 和 POP3 供應商。
· JavaMail 1.1.3 的安裝
要使用 JavaMail 1.1.3 API,請下載 JavaMail 1.1.3 實(shí)現,解開(kāi)Javamail1_1_3.zip文件,并將 mail.jar 文件添加到您的 CLASSPATH 中。除了核心類(lèi),隨版本 1.1.3 實(shí)現一起提供的還有 SMTP 和 IMAP4 供應商。
如果您用 JavaMail 1.1.3 訪(fǎng)問(wèn)一個(gè) POP 服務(wù)器,請下載并安裝一個(gè) POP3 供應商。Sun 就有一個(gè)獨立于 JavaMail 實(shí)現。下載并解開(kāi) pop31_1_1.zip 文件后,將 pop3.jar 也添加到您的 CLASSPATH 中。
其次是JavaBeans Activation Framework 的安裝。JavaMail API 的所有版本都需要 JavaBeans Activation Framework 來(lái)支持任意數據塊的輸入及相應處理。功能似乎不多,但目前許多瀏覽器和郵件工具中都能找到這種基本的 MIME 型支持。下載完框架后,解開(kāi) jaf1_0_1.zip 文件,并將 activation.jar 文件添加到 CLASSPATH 中。
對于 JavaMail 1.2 用戶(hù)來(lái)說(shuō),現在您應該已將 mail.jar 和 activation.jar 文件添加到 CLASSPATH 中了。
而對于 JavaMail 1.1.3 用戶(hù),現在您應該已將 mail.jar、pop3.jar和 activation.jar文件添加到 CLASSPATH 中了。如果不打算用 POP3,就不必將 pop3.jar 添加到 CLASSPATH 中去。
如果您不想更改 CLASSPATH 環(huán)境變量,將 jar 文件復制到您 Java 運行時(shí)環(huán)境(Java Runtime Environment,JRE)目錄下的 lib/ext 目錄中去。例如,J2SE 1.3 發(fā)行版的缺省目錄在 Windows 平臺的 C:\jdk1.3\jre\lib\ext。
Java Mail API有哪些核心類(lèi)
·Javax.mail.Session:Session 類(lèi)定義了一個(gè)基本郵件會(huì )話(huà)(session),是Java Mail API最高層入口類(lèi)。所有其它類(lèi)都是經(jīng)由這個(gè)session 才得以生效。Session 對象用 Java.util.Properties 對象獲取信息,如郵件服務(wù)器、用戶(hù)名、密碼及整個(gè)應用程序中共享的其它信息。
·Javax.mail.Message:一旦獲得 Session 對象,就可以繼續創(chuàng )建要發(fā)送的消息。這由 Message 類(lèi)來(lái)完成。因為 Message 是個(gè)抽象類(lèi),必需用一個(gè)子類(lèi),多數情況下為 Javax.mail.internet.MimeMessage。MimeMessage 是個(gè)能理解 MIME 類(lèi)型和頭的電子郵件消息,正如不同 RFC 中所定義的。雖然在某些頭部域非 ASCII 字符也能被譯碼,但 Message 頭只能被限制為用 US-ASCII 字符。
·Javax.mail.Address:一旦您創(chuàng )建了 Session 和 Message,并將內容填入消息后,就可以用 Address 確定信件地址了。和 Message 一樣,Address 也是個(gè)抽象類(lèi)。您用的是 Javax.mail.internet.InternetAddress 類(lèi)。
·Javax.mail. Authenticator:與 Java.net 類(lèi)一樣,JavaMail API 也可以利用 Authenticator 通過(guò)用戶(hù)名和密碼訪(fǎng)問(wèn)受保護的資源。對于JavaMail API 來(lái)說(shuō),這些資源就是郵件服務(wù)器。JavaMail Authenticator 在 Javax.mail 包中,而且它和 Java.net 中同名的類(lèi) Authenticator 不同。兩者并不共享同一個(gè) Authenticator,因為JavaMail API 用于 Java 1.1,它沒(méi)有 Java.net 類(lèi)別。
要使用 Authenticator,先創(chuàng )建一個(gè)抽象類(lèi)的子類(lèi),并從 getPasswordAuthentication() 方法中返回 PasswordAuthentication 實(shí)例。創(chuàng )建完成后,您必需向 session 注冊 Authenticator。然后,在需要認證的時(shí)候,就會(huì )通知 Authenticator。您可以彈出窗口,也可以從配置文件中(雖然沒(méi)有加密是不安全的)讀取用戶(hù)名和密碼,將它們作為 PasswordAuthentication 對象返回給調用程序。
·Javax.mail.Transport:消息發(fā)送的最后一部分是使用 Transport 類(lèi)。這個(gè)類(lèi)用協(xié)議指定的語(yǔ)言發(fā)送消息(通常是 SMTP)。它是抽象類(lèi),它的工作方式與 Session 有些類(lèi)似。僅調用靜態(tài) send() 方法,就能使用類(lèi)的 缺省 版本:Transport.send(message);或者,讀者也可以從針對自己的協(xié)議的會(huì )話(huà)中獲得一個(gè)特定的實(shí)例,傳遞用戶(hù)名和密碼(如果不必要就不傳),發(fā)送消息,然后關(guān)閉連接。
·Javax.mail.Store:Store類(lèi)實(shí)現特定郵件協(xié)議上的讀、寫(xiě)、監視、查找等操作。通過(guò)Javax.mail.Store類(lèi)可以訪(fǎng)問(wèn)Javax.mail.Folder類(lèi)。
·Javax.mail.Folder:Folder類(lèi)用于分級組織郵件,并提供照Javax.mail.Message格式訪(fǎng)問(wèn)email的能力。
怎樣使用JSP發(fā)送email?
下面我們通過(guò)一個(gè)簡(jiǎn)單的例子,來(lái)說(shuō)明在JSP中郵件是如何發(fā)送的。該例由兩個(gè)文件組成。一個(gè)是HTML文件,用來(lái)建立郵件信息(包括發(fā)送人、接收人、主題等)的表單,并將表單內容發(fā)送給JSP文件;另外一個(gè)是JSP頁(yè)面,負責郵件的發(fā)送。
HTML文件
<HTML>
<HEAD>
<TITLE>發(fā)送郵件</TITLE>
<meta http-equiv="Content-Type" content="text/html; charset=gb2312"></HEAD>
<BODY>
<FORM action="sendmail.jsp" method="post" name="form1">
<TABLE align="center">
<TR>
<TD width="50%">
To:<BR><INPUT name="to" size="25">
</TD>
<TD width="50%">
From:<BR><INPUT name="from" size="25">
</TD>
</TR>
<TR>
<TD colspan="2">
Subject:<BR><INPUT name="subject" size="50">
</TD>
</TR>
<TR>
<TD colspan="2">
<P>Message:<BR>
<TEXTAREA name="text" rows=25 cols=85></TEXTAREA>
</P>
</TD>
</TR>
</TABLE>
<INPUT type="submit" name="cb_submit" value=" Send ">
<INPUT type="reset" name="cb_reset" value=" Clear ">
</FORM>
</BODY>
</HTML>
JSP頁(yè)面的作用就是獲得表單提交過(guò)來(lái)的數據,并將這些數據賦給Java Mail API中相應的對象,最后完成郵件發(fā)送。
sendmail.jsp文件
<%@ page import=" Javax.mail.*, Javax.mail.internet.*, Javax.activation.*,Java.util.*"%>
<html>
<head>
<TITLE>JSP meets JavaMail, what a sweet combo.</TITLE>
</head>
<body>
<%
try{
Properties props = new Properties();
Session sendMailSession;
Store store;
Transport transport;
sendMailSession = Session.getInstance(props, null);
props.put("mail.smtp.host", "smtp.jspinsider.com");
Message newMessage = new MimeMessage(sendMailSession);
newMessage.setFrom(new InternetAddress(request.getParameter("from")));
newMessage.setRecipient(Message.RecipientType.TO, new InternetAddress ( request.getParameter ("to")));
newMessage.setSubject(request.getParameter("subject"));
newMessage.setSentDate(new Date());
newMessage.setText(request.getParameter("text"));
transport = sendMailSession.getTransport("smtp");
transport.send(newMessage);
%>
<P>Your mail has been sent.</P>
<%
}catch(MessagingException m)
{
out.println(m.toString());
}
%>
</body>
</html>
如何發(fā)送HTML類(lèi)型的郵件
在上面的例子中,我們實(shí)現了如何發(fā)送文本格式的郵件,那么HTML格式的郵件該如何發(fā)送呢?那就看看下面的例子吧。
該例由四個(gè)文件組成:
·form.htm:用來(lái)建立郵件信息的表單
·send.jsp:用來(lái)獲取表單提交的信息,并調用mymail.mail.HTML.send()方法發(fā)送郵件
·StringDataSource.Java:用戶(hù)自定義的JavaBean,用來(lái)將郵件的Body部分轉化為HTML格式
·HTML.Java:用戶(hù)自定義的JavaBean,用來(lái)發(fā)送HTML格式的郵件。在send.jsp文件中提到的mymail.mail.HTML.send()方法就在該JavaBean中定義。
form.htm
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=gb2312">
<title> JavaMail - 發(fā)送HTML郵件</title>
</head>
<body>
<form method="post" action="send.jsp">
<table border="0" cellspacing="0" cellpadding="0">
<tr>
<td>SMTP主機:</td>
<td><input type="text" name="smtp" size="80"></td>
</tr>
<tr>
<td>發(fā)信人:</td>
<td><input type="text" name="from" size="80"></td>
</tr>
<tr>
<td>收信人:</td>
<td><input type="text" name="to" size="80"></td>
</tr>
<tr>
<td>抄送人:</td>
<td><input type="text" name="cc" size="80"></td>
</tr>
<tr>
<td>暗送人:</td>
<td><input type="text" name="bcc" size="80"></td>
</tr>
<tr>
<td>主題:</td>
<td><input type="text" name="subject" size="80"></td>
</tr>
<tr>
<td valign="top">內容:</td>
<td><textarea name="body" rows="5" cols="80"></textarea></td>
</tr>
<tr>
<td colspan="2" align="center"><input type="submit" value="發(fā)送"></td>
</tr>
</table>
</form>
</body>
</html>
send.jsp
<%
//變量聲明
Java.lang.String smtp,from,to,cc,bcc,subject,body;
//獲得用戶(hù)輸入數據
smtp = request.getParameter("smtp");
from = request.getParameter("from");
to = request.getParameter("to");
cc = request.getParameter("cc");
bcc = request.getParameter("bcc");
subject = request.getParameter("subject");
if(subject!=null){
subject = new Java.lang.String(subject.getBytes("iso-8859-1"));
}
body = request.getParameter("body");
//發(fā)送郵件
mymail.mail.HTML.send(smtp,from,to,cc,bcc,subject,body);
%>
mymail.jaf.StringDataSource.Java
package mymail.jaf;
public class StringDataSource implements Javax.activation.DataSource
{
private Java.lang.String data;
private Java.lang.String type;
public StringDataSource(Java.lang.String data,Java.lang.String type){
this.data = data;
this.type = type;
}
public Java.io.InputStream getInputStream() throws Java.io.IOException{
return new Java.io.StringBufferInputStream(data);
}
public Java.io.OutputStream getOutputStream() throws Java.io.IOException{
throw new Java.io.IOException("it does not support this method now!");
}
public Java.lang.String getContentType(){
return type;
}
public Java.lang.String getName(){
return " mymail ";
}
}
mymail.mail.HTML.Java
package mymail.mail;
public final class HTML
{
public static void send(
Java.lang.String smtp, /*SMTP主機地址*/
Java.lang.String from, /*發(fā)信人*/
Java.lang.String to, /*收信人*/
Java.lang.String cc, /*抄送人*/
Java.lang.String bcc, /*暗送人*/
Java.lang.String subject, /*主題*/
Java.lang.String body /*內容*/
) throws Java.lang.Exception
{
//變量聲明
Java.util.Properties props; //系統屬性
Javax.mail.Session mailSession; //郵件會(huì )話(huà)對象
Javax.mail.internet.MimeMessage mimeMsg; //MIME郵件對象
//設置系統屬性
props = Java.lang.System.getProperties(); //獲得系統屬性對象
props.put("mail.smtp.host",smtp); //設置SMTP主機
//獲得郵件會(huì )話(huà)對象
mailSession = Javax.mail.Session.getDefaultInstance(props,null);
//創(chuàng )建MIME郵件對象
mimeMsg = new Javax.mail.internet.MimeMessage(mailSession);
//設置發(fā)信人
mimeMsg.setFrom(new Javax.mail.internet.InternetAddress(from));
//設置收信人
if(to!=null)
{
mimeMsg.setRecipients(Javax.mail.Message.RecipientType.TO,Javax.mail. internet.InternetAddress.parse(to));
}
//設置抄送人
if(cc!=null)
{
mimeMsg.setRecipients(Javax.mail.Message.RecipientType.CC,Javax.mail. internet.InternetAddress.parse(cc));
}
//設置暗送人
if(bcc!=null)
{
mimeMsg.setRecipients(Javax.mail.Message.RecipientType.BCC,Javax.mail. internet.InternetAddress.parse(bcc));
}
設置郵件主題
//mimeMsg.setSubject(subject);
mimeMsg.setSubject(subject,"gb2312");
//設置郵件內容,將郵件body部分轉化為HTML格式
mimeMsg.setDataHandler(new Javax.activation.DataHandler(new mymail.jaf. StringDataSource (body,"text/html")));
//發(fā)送郵件
Javax.mail.Transport.send(mimeMsg);
}
}
如何實(shí)現消息和標志的刪除?
消息的刪除涉及到與消息相關(guān)的 Flags(標志)。不同 flag 表示不同的狀態(tài),有些標志由系統定義,而有些則由用戶(hù)自己定義。下面列出在內部類(lèi) Flags.Flag 中預定義的標志:
·Flags.Flag.ANSWERED
·Flags.Flag.DELETED
·Flags.Flag.DRAFT
·Flags.Flag.FLAGGED
·Flags.Flag.RECENT
·Flags.Flag.SEEN
·Flags.Flag.USER
上述這些標志只是標準定義,并不意味著(zhù)所有郵件服務(wù)器或供應商都支持所有這些標志。例如,除了刪除消息標志外,POP 協(xié)議不再支持其它任何標志。檢查是否存在新郵件,這不是個(gè) POP 任務(wù),而是內建于郵件客戶(hù)機的任務(wù)。為找出哪些標志能被支持,可以用 getPermanentFlags() 向 folder 提出請求。
要刪除消息,您可以設置消息的 DELETED flag:
message.setFlag(Flags.Flag.DELETED, true);
首先,請以 READ_WRITE 模式打開(kāi) folder:
folder.open(Folder.READ_WRITE);
然后,當所有消息的處理完成后,關(guān)閉 folder,并傳遞一個(gè) true 值,從而擦除(expunge)有 delete 標志的消息。
folder.close(true);
一個(gè) Folder 的 expunge() 方法可以用來(lái)刪除消息。但 Sun 的 POP3 供應商不支持。其它供應商有的或許能夠實(shí)現這一功能,而有的則不能。IMAP 供應商極有可能實(shí)現此功能。因為 POP 只支持單個(gè)對郵箱的訪(fǎng)問(wèn),對 Sun 的供應商來(lái)說(shuō),您必需關(guān)閉 folder 以刪除消息。
要取消標志,只要傳遞 false 給 setFlag() 方法就行了。想知道是否設置過(guò)標志,可以用 isSet() 檢查。
如何實(shí)現認證?
想必讀者已經(jīng)知道 ,如果需要可以用一個(gè) Authenticator 提示用戶(hù)輸入用戶(hù)名和密碼,而不是將用戶(hù)名和密碼作為字符串傳遞。在這里您會(huì )明確了解怎樣更充分的使用Java Mail API的認證機制。
不用主機、用戶(hù)名和密碼與 Store 相連接,而是設置 Properties 來(lái)?yè)碛兄鳈C,然后告訴 Session 自定義的 Authenticator 實(shí)例,如下所示:
// 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();
然后,創(chuàng )建一個(gè) Authenticator 子類(lèi)并從 getPasswordAuthentication() 方法中返回 PasswordAuthentication 對象。下面就是這樣一種實(shí)現,其中用戶(hù)名和密碼僅占用一個(gè)域。(這不是一個(gè) Swing 工程教程;只要將兩部分輸入同一個(gè)域,用逗號分隔就行。)
import Javax.mail.*;
import Javax.swing.*;
import Java.util.*;
public class PopupAuthenticator extends Authenticator
{
public PasswordAuthentication getPasswordAuthentication()
{
String username, password;
String result = JOptionPane.showInputDialog("Enter ‘username,password‘");
StringTokenizer st = new StringTokenizer(result, ",");
username = st.nextToken();
password = st.nextToken();
return new PasswordAuthentication(username, password);
}
}
因為 PopupAuthenticator 涉及到 Swing,它會(huì )啟動(dòng) AWT 的事件處理線(xiàn)程。這一點(diǎn)基本上要求您在代碼中添加一個(gè)對 System.exit() 的調用來(lái)終止程序。
如何實(shí)現消息的轉發(fā)?
轉發(fā)消息,相對于其他功能來(lái)說(shuō),顯得有些棘手。沒(méi)有單獨的方法可以供調用,讀者必須通過(guò)對組成消息各部分的處理來(lái)組織要轉發(fā)的消息。
一條郵件消息可以由多個(gè)部分組成。在處理 MIME 消息時(shí),消息中每部分都是 BodyPart,再特殊些,是 MimeBodyPart。不同的 body part(信體部件或正文部件)結合成一個(gè)容器,名為 Multipart,再特殊些,就是 MimeMultipart。要轉發(fā)一條消息,您為自己的消息正文創(chuàng )建一個(gè)部件,要轉發(fā)的消息作為另一部件。并且將兩個(gè)部件結合成一個(gè) multipart(多部件)。然后您將這個(gè) multipart 添加到一則已寫(xiě)好恰當地址的消息中,并發(fā)送。
本質(zhì)上就是如此。要將一條消息內容復制到另一條,只要復制 DataHandler (JavaBeans Activation Framework 中的類(lèi))就行了。
// Create the message to forward
Message forward = new MimeMessage(session);
// Fill in header
forward.setSubject("Fwd: " + message.getSubject());
forward.setFrom(new InternetAddress(from));
forward.addRecipient(Message.RecipientType.TO, new InternetAddress(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);
怎樣處理附件?
附件是郵件消息的相關(guān)資源,如通常不包含在消息正文里文本文件、電子表格或圖像等。常見(jiàn)的郵件程序,如 Eudora 和 pine 之類(lèi),可以用 JavaMail API 將資源 attach(附加) 到您的消息上,就可以在收到消息時(shí)得到。
附件的發(fā)送:
發(fā)送附件非常像轉發(fā)消息。您建立各部分以組成完整消息。完成第一部件,即消息正文后,您添加其它部件,其中每個(gè) DataHandler 都代表附件,而不是轉發(fā)消息情況下的共享處理程序。如果從文件中讀附件,附件的數據源是 FileDataSource。而如果從 URL 中讀時(shí),附件的數據源是 URLDataSource。一旦存在 DataSource,只要先把它傳遞給 DataHandler 構造器,最后再用 setDataHandler() 把它附加到 BodyPart。假定您要保留附件的原始文件名,最終要做的是用 BodyPart 的 setFileName() 方法設置與附件相關(guān)的文件名。如下所示:
// Define message
Message 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 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);
就消息引入附件時(shí),若程序是個(gè) servlet (小服務(wù)程序),除告知消息發(fā)送到何處外,還必需上載附件??梢詫?multipart/form-data 表單編碼類(lèi)型(form encoding type)用于每個(gè)上載文件的處理。
<FORM ENCTYPE="multipart/form-data"
method=post action="/myservlet">
<INPUT TYPE="file" NAME="thefile">
<INPUT TYPE="submit" VALUE="Upload">
</FORM>
注意:消息大小由 SMTP 服務(wù)器而不是 JavaMail API 來(lái)限制。如果您碰到問(wèn)題,可以考慮用設置 ms 和 mx 參數的方法增大 Java 堆大小。
附件的獲?。?
從消息中獲取附件比發(fā)送它們棘手些,因為 MIME 沒(méi)有簡(jiǎn)單的關(guān)于附件的概念。當消息包含附件時(shí),消息的內容是個(gè) Multipart 對象。接著(zhù),您需要處理每個(gè) Part,獲取主要內容和附件。標有從 part.getDisposition() 獲得的 Part.ATTACHMENT 配置(disposition)的部件(Part)無(wú)疑就是附件。但是,沒(méi)有配置(以及一個(gè)非文本 MIME 類(lèi)型)和帶 Part.INLINE 配置的部件也可能是附件。當配置要么是 Part.ATTACHMENT,要么是 Part.INLINE 時(shí),這個(gè)消息部件的內容就能被保存。只要用 getFileName() 和 getInputStream() 就能分別得到原始文件名和輸入流。
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());
}
}
saveFile() 方法僅依據文件名創(chuàng )建了一個(gè) File,它從輸入流中將字節讀出,然后寫(xiě)入到文件中。萬(wàn)一文件已經(jīng)存在,就在文件名后添加一個(gè)數字作為新文件名,如果這個(gè)文件名仍存在,則繼續添,直到找不到這樣的文件名為止。
// from saveFile()
File file = new File(filename);
for (int i=0; file.exists(); i++) {
file = new File(filename+i);
}
上面的代碼涵蓋了最簡(jiǎn)單的情況 - 消息中各部件恰當的標記了。要涵蓋所有情況,還要在配置為空時(shí)進(jìn)行處理,并且獲取部件的 MIME 類(lèi)型來(lái)進(jìn)行相應處理。
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, ...
}
...
}
如何一次發(fā)送多個(gè)郵件?
取得必要的Transport對象并調用SendMessage()發(fā)送每一個(gè)郵件。注意在調用之間設置或改變接收者。
Message message = …;
Transport t = session.getTransport("smtp");
t.connect();
message.setRecipient(Message.RecipientType.TO,recipient1);
t.sendMessage(message,recipient);
message.setRecipient(Message.RecipientType.TO,recipient2);
t.sendMessage(message,recipient);
message.setRecipient(Message.RecipientType.TO,recipient3);
t.sendMessage(message,recipient);
t.close();
如何保存郵件?
用MimeMessage類(lèi)的writeTo()方法可以實(shí)現。用Message類(lèi)的對象不能實(shí)現。
FileOutputStream fos = new FileOutputStream("test.mail");
Mimemessage.writeTo(fos);
怎樣發(fā)送帶有圖像的HTML格式郵件?
一些圖像還是放在服務(wù)器上較好,讓用戶(hù)的郵件工具處理。讀者可以將圖像作為附件或HTML體發(fā)送。如果所有附件保存在同一個(gè)目錄下,那么必須用不同的圖像文件名以確保郵件工具不會(huì )顯示其他圖片。另外圖像URL要用絕對路徑,不能用相對路徑。
如何設置∕獲取郵件的優(yōu)先級?
設置郵件的優(yōu)先級,只需在消息頭中添加"X-Priority"屬性:
MimeMessage msg;
Msg.addHeader("X-Priority","1");
同樣道理,要獲取郵件的優(yōu)先級只要獲取"X-Priority"屬性的值就可以了:
String priority = msg.getHeader("X-Priority");
附錄:Java Mail API的基本概念
什么是Java Mail API
JavaMail API 是一個(gè)用于閱讀、編寫(xiě)和發(fā)送電子郵件的可選包(標準擴展)。與 Eudora、pine 及 Microsoft Outlook 相似,這個(gè)包用來(lái)創(chuàng )建郵件用戶(hù)代理(Mail User Agent,MUA) 類(lèi)型程序。API 的主要用途并不在于傳輸、發(fā)送和轉發(fā)消息;這一功能范圍屬于某些應用程序,如 sendmail 及其它郵件傳輸代理(Mail Transfer Agent,MTA)類(lèi)型程序。MUA 類(lèi)型的程序能讓用戶(hù)閱讀和書(shū)寫(xiě)郵件,而它卻依賴(lài) MTA 處理實(shí)際發(fā)送。
什么是SMTP
SMTP(Simple Mail Transfer Protocol),即簡(jiǎn)單郵件傳輸協(xié)議,它定義了發(fā)送電子郵件的機制。在 JavaMail API 環(huán)境中,基于 JavaMail 的程序將和您的公司或因特網(wǎng)服務(wù)供應商的(Internet Service Provider‘s,ISP‘s)SMTP 服務(wù)器通信。SMTP 服務(wù)器可將消息中轉至接收方 SMTP 服務(wù)器,以便最終讓用戶(hù)經(jīng)由 POP 或 IMAP 獲得。這不是要求 SMTP 服務(wù)器成為開(kāi)放的中繼,盡管 SMTP 服務(wù)器支持身份驗證,不過(guò)還是得確保它的配置正確。像配置服務(wù)器來(lái)中繼消息或添加刪除郵件賬號這類(lèi)任務(wù)的實(shí)現,JavaMail API 中并不支持。
什么是POP
POP(Post Office Protocol),即郵局協(xié)議。目前用的是版本3,所以人們通常將它稱(chēng)為 POP3,RFC 1939 定義了這個(gè)協(xié)議。POP 和SMTP一樣,也是一種機制,Internet上大多數人通過(guò)它得到郵件。該協(xié)議規定每個(gè)用戶(hù)只能有一個(gè)郵箱的支持。這就是它所能做的,而這也造成了許多混淆。使用 POP 時(shí),用戶(hù)熟悉的許多性能并不是由 POP 協(xié)議支持的,如查看有幾封新郵件消息這一性能。這些性能內建于如 Eudora 或 Microsoft Outlook 之類(lèi)的程序中,它們能記住一些事,諸如最近一次收到的郵件,還能計算出有多少是新的。所以當使用 JavaMail API 時(shí),如果讀者想要這類(lèi)信息,就只能由自己來(lái)計算了。
什么是IMAP
IMAP(Internet Message Access Protocol),即Internet消息訪(fǎng)問(wèn)協(xié)議,是更高級的用于接收消息的協(xié)議,在 RFC 2060 中有它的定義。目前使用的IMAP版本為4,人們習慣將它稱(chēng)為 IMAP4。在用到 IMAP 時(shí),郵件服務(wù)器必需支持這個(gè)協(xié)議。不能僅僅把使用 POP 的程序用于 IMAP,并指望它支持 IMAP 所有性能。假設郵件服務(wù)器支持 IMAP,基于 JavaMail 的程序可以利用這種情況--用戶(hù)在服務(wù)器上可以有多個(gè)文件夾(folder),并且這些文件夾可以被多個(gè)用戶(hù)共享。
因為有這一更高級的性能,您也許會(huì )認為所有用戶(hù)都會(huì )使用 IMAP。事實(shí)并不是這樣。要求服務(wù)器接收新消息,在用戶(hù)請求時(shí)發(fā)送到用戶(hù)手中,還要在每個(gè)用戶(hù)的多個(gè)文件夾中維護消息。這樣雖然能將消息集中備份,但隨著(zhù)用戶(hù)長(cháng)期的郵件夾越來(lái)越大,到磁盤(pán)空間耗盡時(shí),每個(gè)用戶(hù)都會(huì )受到損失。使用 POP,就能卸載郵件服務(wù)器上保存的消息了。
什么是MIME
MIME(Multipurpose Internet Mail Extensions),即多用途Internet郵件擴展標準。它不是郵件傳輸協(xié)議,而是對傳輸內容的消息、附件及其它的內容定義了格式。這里有很多不同的RFC(Requirement of Comment)文檔:RFC 822、RFC 2045、RFC 2046 和 RFC 2047。作為一個(gè) JavaMail API 的用戶(hù),您通常不必對這些格式操心。無(wú)論如何,一定存在這些格式而且程序會(huì )用到它。
聯(lián)系客服