1. 程式人生 > >Java mail 傳送接收郵件

Java mail 傳送接收郵件

文字郵件:

package mypack;

import java.util.Properties;

import javax.mail.Message;
import javax.mail.MessagingException;
import javax.mail.Session;
import javax.mail.Transport;
import javax.mail.internet.InternetAddress;
import javax.mail.internet.MimeMessage;

public class SendMails {
	private Session session;
	private String sendHost="smtp.sina.com";
	private String sendProtocol="smtp";
	private String username="*****@sina.com";
	private String password="*****";
	private String fromAddr="*****@sina.com";
	private String toAddr="*****@qq.com";
	
	public void init(){
		Properties props = new Properties();
		props.setProperty("mail.transport.protocol", sendProtocol);
		props.setProperty("mail.smtp.class", "com.sun.mail.smtp.SMTPTransport");
		props.setProperty("mail.smtp.host", sendHost);
		session = Session.getDefaultInstance(props);
		session.setDebug(true);
	}
	
	public void sendMessage() throws MessagingException{
		MimeMessage message = new MimeMessage(session);
		InternetAddress[] toAddrs = InternetAddress.parse(toAddr,false);
		message.setRecipients(Message.RecipientType.TO, toAddrs);
		message.setSubject("hello,baby!");
		message.setFrom(new InternetAddress(fromAddr));
		message.setText("hello,baby! how are you!");
	    Transport ts = session.getTransport();
	    ts.connect(sendHost, username, password);
	    ts.sendMessage(message, toAddrs);
	}

	public static void main(String[] args) throws MessagingException {
		// TODO Auto-generated method stub
		SendMails mails = new SendMails();
		mails.init();
		mails.sendMessage();
	}

}
從郵件伺服器獲取郵件
package mypack;

import java.io.IOException;
import java.util.Properties;

import javax.mail.Folder;
import javax.mail.Message;
import javax.mail.MessagingException;
import javax.mail.Session;
import javax.mail.Store;



public class ReceiveMail {
	private Session session;
	private Store store;
	private String receiveProtocol="imap";
	private String username="*****@sina.com";
	private String password="*****";
	private String receivehost="imap.sina.com";
	private String foldername="inbox";
	
	public void init() throws MessagingException{
		Properties props = new Properties();
		props.put("mail.store.protocol",receiveProtocol);
		props.put("mail.imap.class", "com.sun.mail.imap.IMAPStore");
		props.put("mail.imap.auth", "true");
		session = Session.getDefaultInstance(props);
		store= session.getStore(receiveProtocol);
		store.connect(receivehost, username, password);
	}
    
	public void browseMessagesFromFolder() throws MessagingException, IOException{
		Folder folder = store.getFolder(foldername);
		if(folder==null)
			System.out.println(foldername+"不存在");
		folder.open(Folder.READ_ONLY);
		System.out.println("you have "+folder.getMessageCount()+" in your mail folder.");
		System.out.println("you have "+folder.getUnreadMessageCount()+" unread message in inbox.");
		
		Message[] messages = folder.getMessages();
		for(int i=1;i<=messages.length;i++){
			System.out.println("------第"+i+"封郵件");
			folder.getMessage(i).writeTo(System.out);
			System.out.println();
		}
		folder.close(false);
	}
	public static void main(String[] args) throws MessagingException, IOException {
		// TODO Auto-generated method stub
          ReceiveMail mail = new ReceiveMail();
          mail.init();
          mail.browseMessagesFromFolder();
	}

}

一個Multipart物件包含一個或多個BodyPart物件,來組成郵件的正文部分(包括附件)。

public abstract class Multipart extendsObject

            Multipart is a container that holds multiple body parts. Multipart provides methods to retrieve and set its subparts.

        public class MimeMultipart   extendsMultipart

           The MimeMultipart class is an implementation of the abstract Multipart class that uses MIME conventions for the multipart data.

          A MimeMultipart is obtained from a MimePart whose primary type is "multipart" (by invoking the part's getContent() method) or it can be created by a client as part of creating a new MimeMessage..The default multipart subtype is "mixed". The other multipart subtypes, such as "alternative", "related",and so on.

Multipartcontent-type

總體來說,MIME訊息由訊息頭和訊息體兩大部分組成。現在我們關注的是MIME郵件,因此在以下的討論中姑且稱“訊息”為“郵件”。

郵件頭包含了發件人、收件人、主題、時間、MIME版本、郵件內容的型別等重要資訊。每條資訊稱為一個域,由域名後加“: ”和資訊內容構成,可以是一行,較長的也可以佔用多行。域的首行必須“頂頭”寫,即左邊不能有空白字元(空格和製表符);續行則必須以空白字元打頭,且第一個空白字元不是資訊本身固有的,解碼時要過濾掉。

郵件體包含郵件的內容,它的型別由郵件頭的“Content-Type”域指出。常見的簡單型別有text/plain(純文字)text/html(超文字)。有時也會出現的multipart型別,是MIME郵件的精髓。郵件體被分為多個段,每個段又包含段頭和段體兩部分,這兩部分之間也以空行分隔。常見的multipart型別有三種:multipart/mixed, multipart/relatedmultipart/alternative

multipart/mixed:附件。

multipart/related:內嵌資源。

multipart/alternative:純文字與超文字共存

  multipart諸型別的共同特徵是,在段頭指定“boundary”引數字串,段體內的每個子段以此串定界。所有的子段都以--=_”boundary開始,父段則以--=_”boundary” --結束。段與段之間也以空行分隔。

javax.mail.Multipart
屬性
protected String contentType
This field specifies the content-type of this multipart object. It defaults to "multipart/mixed".
Multipart的content-type型別。型別包括"alternative", "mixed", "related", "parallel", "signed"等。
protected Part parent
The Part containing this Multipart, if known.
父Part,一般是message。
protected Vector parts
Vector of BodyPart objects.
方法
1.操作BodyPart
void addBodyPart(BodyPart part)
Adds a Part to the multipart.
void addBodyPart(BodyPart part, int index)
Adds a BodyPart at position index.
BodyPart getBodyPart(int index)
Get the specified Part.
boolean removeBodyPart(BodyPart part)
Remove the specified part from the multipart message.
void removeBodyPart(int index)
Remove the part at specified location (starting from 0).
2.操作父Part
Part getParent()
Return the Part that contains this Multipart object, or null if not known.
void setParent(Part parent)
Set the parent of this Multipart to be the specified Part.
3.取得content-type
String getContentType()
Return the content-type of this Multipart.
4.取得BodyPart數量
int getCount()
Return the number of enclosed BodyPart objects.
javax.mail.internet.MimeMultipart
MimeMultipart(String subtype)
Construct a MimeMultipart object of the given subtype.
建立一個指定子型別的MimeMultipart物件。預設為mixed,你可設定related或alternative等。
設定子型別
void setSubType(String subtype)
Set the subtype.

javax.mail.BodyPart
public abstract class BodyPart implements Part
BodyPart是一個包含在Multipart中的Part。它是一個Part也包含attribute和content。
javax.mail.internet.MimeBodyPart
public class MimeBodyPart extends BodyPart implements MimePart
MimeBodyPart是BodyPart的實現類。


屬性
Multipart parent
The Multipart object containing this BodyPart, if known.
這是和message的區別所在,雖然都實現Part介面,但BodyPart是包含在Multipart中的。它的parent是(Multipart)message.getContent()。
javax.mail.internet.MimeBodyPart
屬性
protected  byte[]   content
Byte array that holds the bytes of the content of this Part.
一個位元組陣列存放BodyPart內容的位元組流。
protected  InputStream   contentStream
If the data for this body part was supplied by an InputStream that implements the SharedInputStream interface, contentStream
 is another such stream representing the content of this body part.
若BodyPart的資料提供一個InputStream,contentStream是另一種流代表BodyPart的內容。
protected  DataHandler   dh
The DataHandler object representing this Part's content.
代表BodyPart內容的DataHandler物件。
protected  InternetHeaders headers
The InternetHeaders object that stores all the headers of this body part.
InternetHeaders 物件存放所有BodyPart的標題。
建構函式
MimeBodyPart()
An empty MimeBodyPart object is created.
建立一個空的MimeBodyPart物件。
MimeBodyPart(InputStream is)
Constructs a MimeBodyPart by reading and parsing the data from the specified input stream.
MimeBodyPart(InternetHeaders headers, byte[] content)
Constructs a MimeBodyPart using the given header and content bytes.
方法
1.操作附件
DataHandler
DataHandler    getDataHandler()
Return a DataHandler for this body part's content.
void  setDataHandler(DataHandler dh)
This method provides the mechanism to set this body part's content.
2.操作附件名
void  setFileName(String filename)
Set the filename associated with this body part, if possible.
設定了附件名稱則會在郵件BodyPart頭中增加一行表示附件的程式碼Content-Disposition: attachment; filename=xxxx.xls
String        getFileName()
Get the filename associated with this body part.
獲取Content-Disposition: attachment; filename=xxxx.xls中的filename。
3.操作正文
void  setText(String text)
Convenience method that sets the given String as this part's content, with a MIME type of "text/plain".
void  setText(String text, String charset)
Convenience method that sets the given String as this part's content, with a MIME type of "text/plain" and the specified charset.
void  setText(String text, String charset, String subtype)
Convenience method that sets the given String as this part's content, with a primary MIME type of "text" and the specified MIME subtype.
以上三個方法都是用於設定MimeBodyPart的內容(文字內容)的,不同之處在於是否設定指定的字元或指定的MIME型別。


javax.mail.BodyPart
public abstract class BodyPart implements Part
BodyPart是一個包含在Multipart中的Part。它是一個Part也包含attribute和content。
javax.mail.internet.MimeBodyPart
public class MimeBodyPart extends BodyPart implements MimePart
MimeBodyPart是BodyPart的實現類。


屬性
Multipart parent
The Multipart object containing this BodyPart, if known.
這是和message的區別所在,雖然都實現Part介面,但BodyPart是包含在Multipart中的。它的parent是(Multipart)message.getContent()。
javax.mail.internet.MimeBodyPart
屬性
protected  byte[]   content
Byte array that holds the bytes of the content of this Part.
一個位元組陣列存放BodyPart內容的位元組流。
protected  InputStream   contentStream
If the data for this body part was supplied by an InputStream that implements the SharedInputStream interface, contentStream
 is another such stream representing the content of this body part.
若BodyPart的資料提供一個InputStream,contentStream是另一種流代表BodyPart的內容。
protected  DataHandler   dh
The DataHandler object representing this Part's content.
代表BodyPart內容的DataHandler物件。
protected  InternetHeaders headers
The InternetHeaders object that stores all the headers of this body part.
InternetHeaders 物件存放所有BodyPart的標題。
建構函式
MimeBodyPart()
An empty MimeBodyPart object is created.
建立一個空的MimeBodyPart物件。
MimeBodyPart(InputStream is)
Constructs a MimeBodyPart by reading and parsing the data from the specified input stream.
MimeBodyPart(InternetHeaders headers, byte[] content)
Constructs a MimeBodyPart using the given header and content bytes.
方法
1.操作附件
DataHandler
DataHandler    getDataHandler()
Return a DataHandler for this body part's content.
void  setDataHandler(DataHandler dh)
This method provides the mechanism to set this body part's content.
2.操作附件名
void  setFileName(String filename)
Set the filename associated with this body part, if possible.
設定了附件名稱則會在郵件BodyPart頭中增加一行表示附件的程式碼Content-Disposition: attachment; filename=xxxx.xls
String        getFileName()
Get the filename associated with this body part.
獲取Content-Disposition: attachment; filename=xxxx.xls中的filename。
3.操作正文
void  setText(String text)
Convenience method that sets the given String as this part's content, with a MIME type of "text/plain".
void  setText(String text, String charset)
Convenience method that sets the given String as this part's content, with a MIME type of "text/plain" and the specified charset.
void  setText(String text, String charset, String subtype)
Convenience method that sets the given String as this part's content, with a primary MIME type of "text" and the specified MIME subtype.
以上三個方法都是用於設定MimeBodyPart的內容(文字內容)的,不同之處在於是否設定指定的字元或指定的MIME型別。


傳送包含圖片的郵件
package mypack;

import java.io.FileOutputStream;
import java.io.IOException;
import java.util.Properties;

import javax.activation.DataHandler;
import javax.activation.FileDataSource;
import javax.mail.Message;
import javax.mail.MessagingException;
import javax.mail.Session;
import javax.mail.Transport;
import javax.mail.internet.InternetAddress;
import javax.mail.internet.MimeBodyPart;
import javax.mail.internet.MimeMessage;
import javax.mail.internet.MimeMultipart;


public class SendMailContainsPic {
	private Session session;
	private String sendHost="smtp.sina.com";
	private String sendProtocol="smtp";
	private String username="*****@sina.com";
	private String password="******";
	private String fromAddr="*****@sina.com";
	private String toAddr="*****@qq.com";
	
	public void init(){
		Properties props = new Properties();
		props.setProperty("mail.transport.protocol", sendProtocol);
		props.setProperty("mail.smtp.class", "com.sun.mail.smtp.SMTPTransport");
		props.setProperty("mail.smtp.host", sendHost);
		props.setProperty("mail.smtp.auth", "true");
	    session = Session.getDefaultInstance(props);
	    session.setDebug(true);
	}
	
	public void sendMessage() throws MessagingException, IOException{
		
		MimeMessage message = new MimeMessage(session);
		message.setFrom(new InternetAddress(fromAddr));
		InternetAddress[] toAddrs = InternetAddress.parse(toAddr,false);
		message.setRecipients(Message.RecipientType.TO, toAddrs);
		message.setSubject("郵件帶圖片");
		
		MimeBodyPart text = new MimeBodyPart();
		text.setContent("這是一封測試郵件","text/html;charset=utf-8");
		
		MimeBodyPart attach = new MimeBodyPart();
		DataHandler dh = new DataHandler(new FileDataSource("src/aa.jpg"));
		attach.setDataHandler(dh);
		attach.setFileName(dh.getName());
		
		MimeMultipart multipart = new MimeMultipart();
		multipart.addBodyPart(text);
		multipart.addBodyPart(attach);
		multipart.setSubType("mixed");
		
		message.setContent(multipart);
		message.saveChanges();
		
		Transport ts = session.getTransport();
		ts.connect(sendHost, username, password);
		
		ts.sendMessage(message, toAddrs);
		
	}

	public static void main(String[] args) throws MessagingException, IOException {
		// TODO Auto-generated method stub
       SendMailContainsPic mailContainsPic = new SendMailContainsPic();
       mailContainsPic.init();
       mailContainsPic.sendMessage();
	}

}

建立一個內含附件的郵件與上一篇文章中建立正文中包含圖片的郵件的原理,甚至程式碼都幾乎相同。也就是使用 JAF 框架中的 FileDataSource 類和 DataHandler 類來獲得給定路徑的資原始檔,JAF 框架中的這兩個類共同協作可以獲知檔案所屬的 MIME 型別,它們會正確地新增到郵件組織結構中的對應訊息頭中。

傳送帶附件的郵件

在 HTML 格式的正文中內含圖片是使用 MimeBody.setContentID() 方法設定對應的資原始檔的唯一識別符號,即 MIME 協議對於郵件的結構組織格式中的 Content-ID 頭欄位;

而在 MIME 郵件中新增附件是使用 MimeBodyPart.setFileName() 方法來關聯 FileSourceData 物件指向的資原始檔。

package mypack;

import java.util.Properties;

import javax.activation.DataHandler;
import javax.activation.FileDataSource;
import javax.mail.Message;
import javax.mail.MessagingException;
import javax.mail.Session;
import javax.mail.Transport;
import javax.mail.internet.AddressException;
import javax.mail.internet.InternetAddress;
import javax.mail.internet.MimeBodyPart;
import javax.mail.internet.MimeMessage;
import javax.mail.internet.MimeMultipart;


public class MixedMail {
	private Session session;
	private String sendHost="smtp.sina.com";
	private String sendProtocol="smtp";
	private String username="*****@sina.com";
	private String password="*****";
	private String from="*****@sina.com";
	private String to="******@qq.com";
	
	public void init(){
		Properties props = new Properties();
		props.put("smtp.sina.com", sendHost);
		props.put("mail.transport.protocol", sendProtocol);
		session = Session.getDefaultInstance(props);
		session.setDebug(true);
	}
	public void sendMessage() throws MessagingException{
		MimeMessage message = new MimeMessage(session);
		InternetAddress[] toAddrs = InternetAddress.parse(to, false);
		message.setFrom(new InternetAddress(from));
		message.setRecipients(Message.RecipientType.TO, toAddrs);
		message.setSubject("美麗的姑娘與優美的音樂");
		
		MimeBodyPart text= new MimeBodyPart();
		text.setContent("漂亮的姑娘<br><img src='cid:dd.jpg'></img>","text/html;charset=utf-8");
		
		MimeBodyPart image = new MimeBodyPart();
		image.setDataHandler(new DataHandler(new FileDataSource("src/mm.jpg")));
		image.setContentID("dd.jpg");
		
		MimeMultipart mp1 = new MimeMultipart();
		mp1.addBodyPart(text);
		mp1.addBodyPart(image);
		mp1.setSubType("related");
		
		MimeBodyPart attach = new MimeBodyPart();
		DataHandler dh = new DataHandler(new FileDataSource("src/Refrain.mp3"));
		attach.setDataHandler(dh);
		attach.setFileName(dh.getName());
		
		MimeBodyPart content = new MimeBodyPart();
		content.setContent(mp1);
		
		MimeMultipart mp2 = new MimeMultipart();
		mp2.addBodyPart(content);
		mp2.addBodyPart(attach);
		mp2.setSubType("mixed");
		
		message.setContent(mp2);
		message.saveChanges();
		
		Transport ts = session.getTransport();
		ts.connect(sendHost, username, password);
		
		ts.sendMessage(message, toAddrs);
		ts.close();
		
	}
	 
	public static void main(String[] args) throws MessagingException {
		MixedMail mail = new MixedMail();
		mail.init();
		mail.sendMessage();
	}

}



參考:

  http://blog.itpub.net/15182208/viewspace-730172/