使用之前,必須了解的基本概念與核心類:Session是郵件操作的接口;Transport是收發郵件所
使用的協議,一般Session會有多個Transport;Message是收發操作的單位;Store是消息的集合,類
似郵件客戶端。每個Store包含一系列的Folder和Message,每個Folder又包含一系列的Folder和Message。
使用的協議,一般Session會有多個Transport;Message是收發操作的單位;Store是消息的集合,類
似郵件客戶端。每個Store包含一系列的Folder和Message,每個Folder又包含一系列的Folder和Message。
屬性名
|
含義
|
java,mail.smtp.user
|
SMTP的缺省用戶名。
|
java,mail.smtp.host
|
|
java,mail.smtp.port
|
要連接的SMTP服務器的端口號,如果connect沒有指明端口號就使用它,缺省值25。
|
java,mail.smtp.connectiontimeout
|
Socket連接超時值,單位毫秒,缺省值不超時。
|
java,mail.smtp.timeout
|
Socket I/O超時值,單位毫秒,缺省值不超時。
|
java,mail.smtp.from
|
|
java,mail.smtp.localhost
|
localhost名,缺省是InetAddress.getLocalHost().getHostName()。如果JDK和name service正確配置,一般不需設置。
|
java,mail.smtp.ehlo
|
如果為false,那么不會嘗試使用EHLO命令登錄,缺省是true。通常EHLO命令失敗,會倒退到HELO命令。這個屬性只有在服務器沒有fail EHLO屬性或沒有實現EHLO屬性。
|
java,mail.smtp.auth
|
缺省是false,如果為true,嘗試使用AUTH命令認證用戶。
|
java,mail.host
|
郵件交互的主機。
|
java,mail.transport.protocol
|
要裝入session的協議(smtp、pop3、imap、nntp)。
|
java,mail.user
|
登錄郵件服務器的用戶名(發送郵件時需要)。
|
java,mail.from
|
發件人地址(發送郵件時需要)。
|
發送郵件
發送郵件主要涉及的類包括:Session、Transport和MimeMessage。如果發送帶附件的郵件還會
涉及:MimeMultipart、DataSource和DataHandler。注意:以下的示例代碼不帶異常處理。
涉及:MimeMultipart、DataSource和DataHandler。注意:以下的示例代碼不帶異常處理。
- 發送不帶附件的郵件:
Properties props= new Properties();
//如果使用connect包含用戶名和密碼
//仍然連接不上,那么有可能是這個屬性沒有設置。
//導致服務器不驗證
props.put("mail.smtp.auth", "true");
//也可實現一個自定義的Authenticator,并調用
//getDefaultInstance(java.util.Properties props, Authenticator authenticator)
//來完成驗證。個人覺得不如使用connect方便。
Transport transport= session.getTransport("smtp");
MimeMessage message= new MimeMessage( session);
InternetAddress from= new InternetAddress( "James.Hu@chinacodeline.com", "James.Hu");
message.setFrom( from);
InternetAddress to= new InternetAddress("foxgem_magic@yahoo.com.cn");
//指定收件人的類型
message.setRecipient( MimeMessage.RecipientType.TO, to);
message.setSubject( "This is a test.");
//文本內容,就直接使用這個函數。
//如果內容不是純文本,那么使用setContent指定mime type。
message.setText( "檢查文件");
//加上這句話表示郵件完成
message.saveChanges();
//連接并驗證
transport.connect("mail.chinacodeline.com", "james.hu@chinacodeline.com", "密碼");
transport.sendMessage( message, message.getAllRecipients());
transport.close();
props.put("mail.smtp.auth", "true"); Session session= Session.getDefaultInstance( props);
|
- 發送帶附件的郵件:
Properties props= new Properties();
props.put("mail.smtp.auth", "true");
Session session= Session.getDefaultInstance( props);
Transport transport= session.getTransport("smtp");
MimeMessage msg= new MimeMessage( session);
msg.setFrom( new InternetAddress( "james.hu@chinacodeline.com", "foxgem"));
msg.setRecipient( MimeMessage.RecipientType.TO
, new InternetAddress("foxgem_magic@yahoo.com.cn"));
msg.setSubject("mail with single file");
//把郵件內容看作多個組成部分,每部分分別組織自己的內容。最后
//通過這個類組合起來一起發出。
MimeMultipart content= new MimeMultipart();
MimeBodyPart part1= new MimeBodyPart();
part1.setText("pls check the file");
MimeBodyPart part2= new MimeBodyPart();
//附件如果是文件,一般都是使用FileDataSource
//如果是從其他方面獲得,那么使用對應的DataSource。
//如,若是來自url,那么就使用URLDataSource
DataHandler dh= new DataHandler( fileDs);
part2.setDataHandler( dh);
//標記為附件,否則當郵件客戶端(如OE)收到后,直接在郵件中顯示內容。
part2.setDisposition( MimeBodyPart.ATTACHMENT);
//設置附件的文件名
part2.setFileName( "test.txt");
content.addBodyPart( part1);
content.addBodyPart( part2);
msg.setContent( content);
msg.saveChanges();
transport.connect("mail.chinacodeline.com", "james.hu@chinacodeline.com", "密碼");
transport.sendMessage( msg, msg.getAllRecipients());
transport.close();
DataSource fileDs= new FileDataSource( "d:/test.txt");
|
接收郵件
接收郵件涉及的類:Session、Store、Folder和MimeMessage。如果發送帶附件的郵件還會
涉及:MimeMultipart、DataSource和DataHandler。注意:以下的示例代碼不帶異常處理。
涉及:MimeMultipart、DataSource和DataHandler。注意:以下的示例代碼不帶異常處理。
- 接收不帶附件的郵件:
Properties props= new Properties();
Session session= Session.getDefaultInstance( props);
Store store= session.getStore( "pop3");
store.connect( "pop.mail.yahoo.co.uk", "foxgem_magic", "密碼");
//找到缺省的目錄
Folder root= store.getDefaultFolder();
//也可指定打開的目錄,如Folder inbox= root.getFolder( “inbox”);
Folder[] folders= root.list();
for( int j=0; j< folders.length; j++){
//打開folder
folders[j].open( Folder.READ_WRITE);
Message[] msgs= folders[j].getMessages();
for(int i=0; i< msgs.length; i++){
System.out.println( "subject:"+ msgs[i].getSubject());
System.out.println( "content:"+ msgs[i].getContent().toString());
}
//檢查是否有新郵件。
System.out.println( folders[j].hasNewMessages());
folders[j].close( false);
}
store.close();
|
- 接收帶附件的郵件:
Properties props= new Properties();
Session session= Session.getDefaultInstance( props);
Store store= session.getStore( "pop3");
store.connect( "pop.mail.yahoo.co.uk", "foxgem_magic", "密碼");
Folder root= store.getDefaultFolder();
Folder[] folders= root.list();
for( int i=0; i< folders.length; i++){
folders[i].open( Folder.READ_ONLY);
Message[] msgs= folders[i].getMessages();
for( int j=0; j< msgs.length; j++){
Object content= msgs[j].getContent();
//注意Multipart并不是判定是否是附件的標準
if( content instanceof Multipart){
int count= ((Multipart)content).getCount();
for( int k=0; k< count; k++){
BodyPart part= ((Multipart)content).getBodyPart(k);
String disposition= part.getDisposition();
//判斷是否是附件
if( null!= disposition &&
disposition.equalsIgnoreCase( Part.ATTACHMENT)){
BufferedReader br= new BufferedReader( new InputStreamReader(
part.getInputStream()));
for( String line= br.readLine(); null!= line; line= br.readLine()){
System.out.println( line);
}
}
}
}
}
}
store.close();
|
其他操作
接收和發送是最通常的郵件操作,除此之外,一般還有:
- 復制、刪除和移動郵件:這些操作都必須要Folder以讀寫方式打開,且是在Folder關閉
之后起作用。
之后起作用。
//刪除
folder.open(Folder.READ_WRITE);
message.setFlag(Flags.Flag.DELETED, true);
folder.close(true);
|
//移動,另一種形式的設置消息標志位。
inbox.copyMessages(xml_msgs, xml_dev);
Flags delete_flag = new Flags(Flags.Flag.DELETED);
inbox.setFlags(xml_msgs, delete_flag, true);
inbox.expunge();
|
考慮實現通過交互性更強的形式來進行這些操作,如顯示郵件列表的web頁,為了對指定
的郵件進行操作,需要使用Message的Message number。注意,它的值并不是一定,會因為其
他郵件(如另一人從另一個界面刪除了一個郵件)的被刪除而改變。因此,在實際使用時還
需要輔助其他的手段。
的郵件進行操作,需要使用Message的Message number。注意,它的值并不是一定,會因為其
他郵件(如另一人從另一個界面刪除了一個郵件)的被刪除而改變。因此,在實際使用時還
需要輔助其他的手段。
- 回復郵件
//false,只回復給發件人;true,是回復全體。
MimeMessage reply = (MimeMessage)message.reply(false);
reply.setFrom(new InternetAddress("president@whitehouse.gov"));
reply.setText("Thanks");
Transport.send(reply);
|
- 消息轉發:創建一個新郵件的BodyPart,將要轉發的消息復制到新郵件的一個BodyPart中。
2著結合成一個MultiPart,作為新郵件的內容發出。
2著結合成一個MultiPart,作為新郵件的內容發出。
Message forward = new MimeMessage(session);
forward.setSubject("Fwd: " + message.getSubject());
forward.setFrom(new InternetAddress(from));
forward.addRecipient(Message.RecipientType.TO, new InternetAddress(to));
//創建新郵件的內容
Multipart multipart = new MimeMultipart();
//創建新郵件的BodyPart
BodyPart messageBodyPart = new MimeBodyPart();
messageBodyPart.setText( "Here you go with the original message:\n\n");
multipart.addBodyPart(messageBodyPart);
//復制要轉發的郵件,
messageBodyPart = new MimeBodyPart();
//要將一條消息內容復制到另一條,只要復制DataHandler就可以了
messageBodyPart.setDataHandler(message.getDataHandler());
multipart.addBodyPart(messageBodyPart);
forward.setContent(multipart);
Transport.send(forward);
|
- 查找郵件,使用SearchTerm來進行。具體的SearchTerm查看相應的文檔。
SearchTerm to = new RecipientStringTerm(Message.RecipientType.TO,
"xml.dev@lists.xml.org");
SearchTerm cc = new RecipientStringTerm(Message.RecipientType.CC,
"xml.dev@lists.xml.org");
SearchTerm xml_search = new OrTerm(to, cc);
Messages[] xml_msgs = inbox.search(xml_search);
|
- 郵件的編碼主要用于非英文的支持。(注意,上述的例子中有中文,但是沒有這么做就
成功地接收并顯示了中文文字的內容。具體的使用還有待嘗試)
成功地接收并顯示了中文文字的內容。具體的使用還有待嘗試)
編碼:
String foreign_str = ".....";
String usable_str = MimeUtility.encodeText(foreign_str);
message.setText(usable_str);
解碼:
String msg_str = message.getText();
String foreign_str = MimeUtility.decodeText(msg_str);
textfield.setText(foreign_str);
|