?? java資源網 javamail常見問題.htm
字號:
JavaMail API 包,你將需要訪問 IMAP 或 POP3 郵件服務器(用于閱讀郵件)和/或 SMTP
郵件服務器(用于發送郵件)。這些郵件服務器通常由 Internet
服務提供商提供,或者作為組織網絡基礎結構的一部分。如果你不必訪問這樣的郵件服務器,請往下看。</P>
<P><B>問. </B>從哪里可以獲得必要的郵件服務器?<BR><B>答:</B><FONT
color=#594fbf>Sun Java System Messaging Server</FONT> 可用于
Solaris 和 Windows 平臺。華盛頓大學的 IMAP 服務器支持多種平臺 (UNIX、32 位 Windows
等)。可從如下地址獲取源代碼:<FONT
color=#594fbf>ftp://ftp.cac.washington.edu/imap/imap.tar.Z</FONT>。其他的許多供應商提供了支持
Internet 標準的郵件服務器。可以從 <FONT color=#594fbf>IMAP
Connection</FONT> 和 <FONT color=#594fbf>Internet Mail
Consortium</FONT> 獲得更多信息。</P>
<P><B>問.
</B>我應該使用什么主機名、用戶名或密碼?<BR><B>答:</B>我們不提供郵件服務器讓你使用。你必須使用自己的郵件服務器,或者使用
Internet 服務提供商或你所工作的公司提供的郵件服務器。網絡管理員可能給你一些必要的信息用于配置
JavaMail,以便同郵件服務器一起工作。</P>
<P><B>問. </B>我如何配置 JavaMail 通過代理服務器工作?<BR><B>答:</B>大多數代理服務器只支持
HTTP 協議。JavaMail 沒有使用 HTTP
協議來閱讀或發送郵件。使用代理服務器的一個主要原因是為了允許企業網絡中的 HTTP 請求通過企業防火墻。防火墻通常會阻止對
Internet 的大多數訪問,但允許來自代理服務器的請求通過。此外,企業網絡內部的郵件服務器將為郵件執行類似的功能,通過
SMTP 接收消息,然后將它們轉發到 Internet
上的最終目的地,以及接收傳入的消息,然后將它們發送到合適的內部郵件服務器。</P>
<P>如果你的代理服務器支持 SOCKS V4 或 V5 協議 (<FONT
color=#594fbf>http://www.socks.nec.com/aboutsocks.html</FONT>,
<FONT color=#594fbf>RFC1928</FONT>),并允許匿名連接,可以告訴 Java 運行時把所有的
TCP socket 直接連接到 SOCKS 服務器。參閱 <FONT
color=#594fbf>http://java.sun.com/j2se/1.4/docs/guide/net/properties.html</FONT>,獲取
<CODE>socksProxyHost</CODE> 和 <CODE>socksProxyPort</CODE>
屬性的最新文檔。這些是系統級屬性,而不是 JavaMail
會話屬性。當調用應用程序時,它們可以從命令行中設置,例如:<CODE>java
-DsocksProxyHost=myproxy ...</CODE>。這個工具可用于指出從 JavaMail 到
SOCKS 代理服務器進行 SMTP、IMAP 和 POP3 通信。注意,設置這些屬性將告訴 <B>所有</B> TCP
socket 連接到 SOCKS 代理,在應用程序的其他方面上,這可能會帶來負面影響。</P>
<P>假如沒有這樣的 SOCKS 服務器,如果想使用 JavaMail
來直接訪問防火墻外部的郵件服務器,那將需要配置防火墻來允許這一訪問。一個簡單的 HTTP 代理 Web 服務器是足夠的。
</P>
<P><B>問. </B>如何在 Windows NT 中設置 CLASSPATH?<BR><B>答:</B>詳細說明可從
<FONT color=#594fbf>這里</FONT> 獲得。</P>
<P><B>問. </B>當試圖在 Linux
中運行程序時,得到了非常奇怪的錯誤消息,而且程序運行失敗了。錯誤在哪里?<BR><B>答:</B>通常,錯誤消息看起來像下面這樣:</P><PRE>Exception in thread "main"
java.lang.VerifyError:(Class:com/sun/mail/pop3/POP3Store,
method: finalize Signature :()V)
Illegal use of nonvirtual function call
</PRE>
<P></P>問題是由于在 Linux 上,使用的 unzip 命令是有 bug 的版本,這樣解壓縮 JavaMail
下載包時,unzip 命令破壞了 mail.jar 文件。獲取更新版本的 unzip 命令或使用 JDK 的 jar
命令來解壓縮下載包。
<P></P>
<P><B>問. </B>在運行于 SecurityManager 下面的應用程序中,我如何使用
JavaMail;我必須授予應用程序和 JavaMail 什么權限?<BR><B>答:</B>在具有
SecurityManager 的 JDK 1.2(或更新版本)中,當使用 JavaMail 時,JavaMail 讀取
mail.jar 文件中的配置文件有時會失敗。在從 activation.jar 文件中讀取配置文件時,JavaBeans
Activation Framework 可能也有相同的問題。這些默認配置文件是作為“資源”文件存儲的,并且存儲在 jar
文件的 META-INF 目錄中。</P>
<P>有許多調試技術可用于決定這是否是個問題。設置 Session 屬性“mail.debug”為 true(或調用
<CODE>session.setDebug(true)</CODE>),將導致 JavaMail
在試圖加載各個配置文件時打印調試消息。形如“DEBUG: can't load default providers
file”(DEBUG: 不能加載默認提供程序文件) 的消息指出這個問題可能存在。同樣,設置 System
屬性“javax.activation.debug”為“true”(例如,通過使用 "java
-Djavax.activation.debug=true ..." 來運行程序),將導致 JAF
在試圖加載各個資源文件時打印調試消息。最后,通過設置 system 屬性“java.security.debug”
為“access:failure”(例如,通過使用“java
-Djava.security.debug=access:failure ...”來運行程序),JDK
可以產生有用的調試輸出。</P>
<P>除了讀取配置文件的必要權限外,應用程序(和
JavaMail)也將需要一定的權限才可以連接到它使用的郵件服務器。如果應用程序使用 System 屬性來配置
JavaMail(例如,像許多 JavaMail 演示程序所做的那樣,通過傳遞從
<CODE>System.getProperties()</CODE> 中返回的 Properties 對象到
Session 構造函數),它也將需要一定的權限才可以使用 System Properties
對象。另外,應用程序可以使用自己的 Properties 對象,以及確信設置 "mail.from" 屬性 或
"mail.user" 和 "mail.host" 屬性(參見
InternetAddress.getLocalAddress() 方法)。</P>
<P>在 JDK 1.2 SecurityManager 中,為了使應用程序能夠使用
JavaMail,應用程序、JavaMail 和 JAF
將需要某些權限,比如下面的一些權限(一定要使用適當的值替換主機名和路徑名);把這些權限添加到應用程序使用的安全策略文件中。</P>
<P><!-- BEGIN VCD7 CODE SAMPLE COMPONENT -->
<TABLE class=grey4 cellSpacing=0 cellPadding=10 width="100%"
border=0>
<TBODY>
<TR>
<TD><PRE>grant {
// following two permissions allow
// access to default config files
permission java.io.FilePermission
"/path/to/mail.jar", "read";
permission java.io.FilePermission
"/path/to/activation.jar", "read";
// following to use SMTP
permission java.net.SocketPermission
"SMTPHOST:25", "connect,resolve";
// following to use IMAP
permission java.net.SocketPermission
"IMAPHOST:143", "connect,resolve";
// following to use POP3
permission java.net.SocketPermission
"POP3HOST:110", "connect,resolve";
// following needed if System.getProperties() is used
permission java.util.PropertyPermission
"*", "read,write";
};
</PRE></TD></TR></TBODY></TABLE><SPAN class=sp20></SPAN><BR><!-- END VCD7 CODE SAMPLE COMPONENT -->
<P></P>
<P><B>問. </B>如何配置 Web 服務器來運行 JavaMail 演示
servlet?<BR><B>答:</B>針對以下 Web 服務器的指導說明可從這里獲得:
<UL>
<LI><FONT color=#594fbf>Tomcat</FONT>
<LI><FONT color=#594fbf>Apache with JServ </FONT>
<LI><FONT color=#594fbf>iPlanet Web Server</FONT>
<LI><FONT color=#594fbf>Java Web Server</FONT> </LI></UL>
<P></P>
<P><B>問. </B>當在 servlet 中使用 JavaMail 時,未找到任何的 JavaMail
類。我已經在服務器的 CLASSPATH 中添加了 mail.jar?<BR><B>答:</B>當改變 CLASSPATH
時,通常有必要完全重啟 Web 服務器。</P>
<P><B>問. </B>我的 servlet 可以找到 JavaMail 類,但 JavaMail
抱怨它不能找到針對“smtp”或“imap”的服務提供程序或地址類型“rfc822”。<BR><B>答:</B>通常這是因為
JavaMail 無法訪問 mail.jar 中的配置文件,而這可能是由于安全權限問題造成的;參見 <FONT
color=#9966cc>本條目</FONT>,獲取更多的細節。也保證你沒有提取 mail.jar 內容;在服務器的
CLASSPATH 中,應該包括未更改的 mail.jar 文件。</P>
<P><B>問. </B>在哪里可以找到 jws.jar?我已經安裝了 Java Web Server 2.0,并試圖運行
JavaMailServlet。README 文件指示我在 CLASSPATH 中添加
jws.jar。<BR><B>答:</B>jws.jar 不再與 Java Web Server
一起發行(在以前版本中,它們是一起發行的),因此不需要在 CLASSPATH 中添加它。只要在 CLASSPATH 中添加
mail.jar 和 activation.jar,然后重啟 Java Web Server。 </P>
<P><STRONG><FONT size=+1>編程</FONT></STRONG>
<P>
<P><B>問. </B>從哪里可以學習有關 Internet 郵件的基礎知識,它是我高效編寫 JavaMail
程序需要知道的?<BR><B>答:</B>參見我們的 Web 頁中提及的 <FONT
color=#594fbf>參考圖書</FONT> 中的一本,獲得有關 Internet
電子郵件、MIME、SMTP、IMAP 和 POP3 等的背景信息。</P>
<P><B>問. </B>如何調試使用 JavaMail API 的應用程序?<BR><B>答:</B>可通過在代碼中調用
Session 對象上的 <CODE>setDebug(true)</CODE>
方法來打開調試模式。這將造成在控制臺中打印調試消息,包括協議跟蹤信息。如果您認為在 JavaMail 中發現了
bug,就將這個跟蹤及以下信息發送給我們:重生成問題的測試用例、使用的平臺、使用的 JDK 的版本和使用的郵件服務器
(IMAP, SMTP) 的名稱和版本。</P>
<P><B>問. </B>如何發送帶有附件的消息? <BR><B>答:</B>帶有附件的消息采用 MIME
多部分消息來表示,其中第一部分是消息的主體,其他的部分是附件。有大量的例子,它們展示了如何在演示程序中構建這種消息,JavaMail
下載包包含了這些演示程序。</P>
<P><B>問. </B>如何閱讀帶有附件的消息并保存附件?<BR><B>答:</B>如前面描述,在 MIME
中,帶有附件的消息是作為多部分消息表示的。在簡單的例子中,<CODE>Message</CODE> 對象的
<CODE>getContent</CODE> 方法的結果將是一個 <CODE>MimeMultipart</CODE>
對象。多部分對象的第一個主體部分將是消息的主文本。其他的主體部分將是附件。<CODE>msgshow.java</CODE>
演示程序展示了如何在消息中遍歷所有的多部分對象,并提取各個主體部分數據。<CODE>getDisposition</CODE>
方法將給你一個提示,指出主體部分是否應該內嵌顯示,或者應該將其考慮成附件(但請注意,不是所有的發件人都提供這一信息)。</P>
<P>為了將主體部分中的數據保存到文件(比如),請使用 <CODE>getInputStream</CODE>
方法來訪問附件內容,并將數據復制到 <CODE>FileOutputStream</CODE>。</P>
<P>注意,也有一些更復雜的情形也要處理。例如,一些發件人把主體作為純文本和 html 發送。通常,這將作為
<CODE>multipart/alternative</CODE> 內容(和
<CODE>MimeMultipart</CODE>
對象)出現在簡單的文本主體部分的位置中。經過數字簽名或加密的消息甚至會更復雜。處理所有的這些情形可能具有挑戰性。請參考各種
MIME 規范和我們主頁上列出的其他 <FONT color=#594fbf>參考資料</FONT>。</P>
<P><B>問. </B>什么是“中斷支持”(disconnected
support)?<BR><B>答:</B>支持中斷操作的郵件客戶端將允許用戶訪問遠程消息存儲(比如
IMAP)中消息,緩存這些消息中的一些消息的(部分)到本地,然后斷開到服務器的連接。當處在斷開連接狀態中,郵件客戶端可以訪問已經緩存的消息,可能也可以刪除它們或將它們保存到其他文件夾。當郵件客戶端下一次連接到遠程消息存儲時,本地所做變更會與遠程存儲同步。同樣,中斷支持可以允許客戶端在斷開與服務器連接時“發送”消息,在到服務器的連接可用前,消息會進行排隊。也請參閱
<FONT color=#594fbf>RFC1733</FONT>。</P>
<P><B>問. </B>如何使用 JavaMail API 來支持中斷操作?<BR><B>答:</B>JavaMail
API 規范定義了一些接口,郵件客戶端可以使用這些接口來支持中斷操作。我們的 IMAP
提供程序實現了這些接口(UIDFolder 接口)。</P>
<P><B>問. </B>我如何使用 JavaMail API
來發送安全的電子郵件?<BR><B>答:</B>JavaMail API 目前不支持發送或接收安全電子郵件。JavaMail
API
的體系結構使得可以在以后很容易地添加這一支持,我們可以添加支持,第三方也可以添加支持。有關當前電子郵件安全標準(S/MIME
和 PGP)的信息,可以從如下站點找到: <FONT
color=#594fbf>http://www.imc.org/smime-pgpmime.html</FONT>。
請瀏覽我們的 <FONT color=#594fbf>第三方產品</FONT> 頁,獲取來自其他供應商的解決方案。</P>
<P><B>問. </B>writeTo() 方法生成了消息文件,但消息中的一些行既不是數據的規范 MIME 表示(即使用
CRLF 來結束行),又沒有使用我的平臺的規范行分隔符(例如 UNIX
上的“\n”)。如果我需要這些表示時,如何獲得它們當中的任何一種表示?<BR><B>答:</B>不管是哪種情形,你都將需要創建合適的
FilterOutputStream 對象來傳遞給
<CODE>writeTo()</CODE>。FilterOutputStream
將需要接受特定的一些行,它們具有任何常見終止符,然后寫出另外的一些特定行,它們只具有期望的行終止符。下面是這種過濾器的一些例子。<CODE><FONT
color=#594fbf>NewlineOutputStream</FONT></CODE>
轉換到本地平臺的行終止符,當將消息寫到文件時,它是有用的。<CODE><FONT
color=#594fbf>CRLFOutputStream</FONT></CODE> 轉換到 MIME 規范 CRLF
終止符,當需要規范 MIME 格式時(比如計算數字簽名),它是有用的。</P>
<P><B>問. </B>我可以使用 JavaMail API
來實現郵件服務器嗎?<BR><B>答:</B>JavaMail API
設計目的不是幫你實現郵件服務器。但是,對你來說,一些實用工具類,比如 MIME
消息解析類,可能是有用的。通常您會發現,JavaMail API
是在“簡單”而不是在“強有力”方面出錯。對于郵件客戶端,那是合適的,但對于郵件服務器,結果可能是不同的。</P>
<P><B>問. </B>我可以使用 JavaMail API
在我的郵件服務器上添加新的用戶賬戶、刪除用戶賬戶或改變用戶賬戶的密碼嗎?<BR><B>答:</B>JavaMail API
不包括任何工具,用于添加、刪除或修改用戶賬戶。在這一方面是沒有標準的,每個郵件服務器對它的處理是不同的。</P>
<P><B>問. </B>為什么 MimeMessage 類沒有實現
Serializable,這樣我就可以將消息序列化到磁盤,并在以后讀回它?<BR><B>答:</B>JavaMail API
是在現有電子郵件系統上面設計的,并使用了現有的消息格式。對于這樣的一些實現,使用 Java
序列化能力既不是必要的,也不是有用的,因此,不能將它作為 JavaMail API 的目標來考慮。</P>
<P>有關序列化 Message 的困難部分是保留某些指針,它們指向 Folder(文件夾)、Store(存儲)和
Session(會話)。如果只想保存消息的內容,而不是對象本身,消息的 <CODE>writeTo</CODE>
方法將為你完成這一切。如果想根據序列化消息創建整個電子郵件系統,您應該能夠編寫 Message 等的子類,并在子類中實現
Serializable。</P>
<P>如果想序列化自己的引用了 MimeMessages的其他對象,那么你的對
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -