Java郵件發(fā)送

Java Mail 簡介

常見的郵件協(xié)議包括:

  1. SMTP(Simple Mail Transfer Protocol):即簡單郵件傳輸協(xié)議,它是一組用于由源地址到目的地址傳送郵件的規(guī)則,由它來控制信件的中轉(zhuǎn)方式。
  2. POP3(Post Office Protocol - Version 3):即郵局協(xié)議版本 3 ,用于接收電子郵件的標準協(xié)議。
  3. IMAP(Internet Mail Access Protocol) :即 Internet 郵件訪問協(xié)議。是 POP3 的替代協(xié)議。

這三種協(xié)議都有對應(yīng)SSL加密傳輸?shù)膮f(xié)議,分別是 SMTPS,POP3S 和 IMAPS 。

MIME(Multipurpose Internet Mail Extensions) :即多用途因特網(wǎng)郵件擴展標準。它不是郵件傳輸協(xié)議。但對傳輸內(nèi)容的消息、附件及其它的內(nèi)容定義了格式。

JavaMail 是由 Sun(現(xiàn) Oracle) 發(fā)布的用來處理 email 的 API 。它并沒有包含在 Java SE 中,而是作為 Java EE 的一部分。JavaMail下載地址。

下載的文件內(nèi)容如下:

README.txt:整體介紹JavaMail,需要看一下
docs/javadocs:The JavaMail API javadocs,需要看一下
mail.jar:包括JavaMail API和所有service providers,大部分用戶只需要該jar包
lib/mailapi.jar :只有JavaMail API
lib/imap.jar:The IMAP service provider
lib/smtp.jar:The SMTP service provider
lib/pop3.jar:The POP3 service provider
lib/dsn.jar:multipart/report DSN message support
demo:demo示例,簡單了解,有需要再看

郵件傳輸過程

郵件的傳輸過程如下圖:

transport

可以看出,收發(fā)郵件的步驟如下:
創(chuàng)建一個 Session 對象。
Session 對象創(chuàng)建一個 Transport 對象 /Store 對象,用來發(fā)送 / 保存郵件。
Transport 對象 /Store 對象連接郵件服務(wù)器。
Transport 對象 /Store 對象創(chuàng)建一個 Message 對象 ( 也就是郵件內(nèi)容 ) 。
Transport 對象發(fā)送郵件; Store 對象獲取郵箱的郵件。

可以看出,JavaMail 核心類包括:

javax.mail.Session:上下文環(huán)境信息,如服務(wù)器的主機名、端口號、協(xié)議名稱等
javax.mail.Message:郵件模型,發(fā)送郵件和接收郵件的媒介,封裝了郵件的信息,如發(fā)件人、收件人、郵件標題、郵件內(nèi)容等
javax.mail.Transport:連接郵件SMTP服務(wù)器,發(fā)送郵件
javax.mail.Store:連接郵件POP3、IMAP服務(wù)器,收取郵件

核心類介紹

Session

Session 表示一個郵件會話,主要作用包括兩個方面:

接收各種配置屬性信息:通過 Properties 對象設(shè)置的屬性信息;
初始化 JavaMail 環(huán)境:根據(jù) JavaMail 的配置文件,初始化 JavaMail 環(huán)境,以便通過 Session 對象創(chuàng)建其他重要類的實例。

Transport

Session 類中的 getTransport () 有多個重載方法,可以用來創(chuàng)建 Transport 對象。

connect : 如果設(shè)置了認證命令(mail.smtp.auth) ,那么使用 Transport 類的 connect 方法連接服務(wù)器時,則必須加上用戶名和密碼。
sendMessage : Transport 類的 sendMessage 方法用來發(fā)送郵件消息。
close : Transport 類的 close 方法用來關(guān)閉和郵件服務(wù)器的連接。

Store

Session 類中的 getStore () 有多個重載方法,可以用來創(chuàng)建 Store 對象。

connect : 同上
getFolder : Store 類的 getFolder 方法可以 獲取郵箱內(nèi)的郵件夾 Folder 對象
close : Store 類的 close 方法用來關(guān)閉和郵件服務(wù)器的連接。

Message

Message 是抽象類,多數(shù)情況下使用子類 javax.mail.internet.MimeMessage 。
MimeMessage 代表 MIME 類型的電子郵件消息。

要創(chuàng)建一個 Message ,需要將 Session 對象傳遞給 MimeMessage 構(gòu)造器:
MimeMessage message = new MimeMessage(session);

setFrom :設(shè)置郵件的發(fā)件人
setRecipient :設(shè)置郵件的發(fā)送人、抄送人、密送人

三種預定義的地址類型是:
Message.RecipientType.TO :收件人
Message.RecipientType.CC :抄送人
Message.RecipientType.BCC :密送人

setSubject :設(shè)置郵件的主題
setContent :設(shè)置郵件內(nèi)容
setText :如果郵件內(nèi)容是純文本,可以使用此接口設(shè)置文本內(nèi)容。

Address

Address 用來確定信件地址。和 Message 一樣, Address 也是個抽象類。常用的是 javax.mail.internet.InternetAddress 類。

若創(chuàng)建的地址只包含電子郵件地址,只要傳遞電子郵件地址到構(gòu)造器就行了:Address address = new InternetAddress("[email address]");

Authenticator

要使用驗證者 Authenticator,先創(chuàng)建一個抽象類的子類,并從 getPasswordAuthentication() 方法中返回 PasswordAuthentication 實例。創(chuàng)建完成后,您必需向 session 注冊 Authenticator 。然后,在需要認證的時候,就會通知 Authenticator 。

簡單的例子

發(fā)送文本郵件

public static void main(String[] args) throws Exception {
    Properties prop = new Properties();
    prop.setProperty("mail.debug", "true");
    prop.setProperty("mail.host", MAIL_SERVER_HOST);
    prop.setProperty("mail.transport.protocol", "smtp");
    prop.setProperty("mail.smtp.auth", "true");
 
    Session session = Session.getInstance(prop);
    Transport ts = session.getTransport();
    ts.connect(MAIL_SERVER_HOST, USER, PASSWORD);
    MimeMessage message = new MimeMessage(session);
    message.setFrom(new InternetAddress(MAIL_FROM)); 
    message.setRecipient(Message.RecipientType.TO, new InternetAddress(MAIL_TO)); // 郵件的收件人
    message.setRecipient(Message.RecipientType.CC, new InternetAddress(MAIL_CC)); // 郵件的抄送人
    message.setRecipient(Message.RecipientType.BCC, new InternetAddress(MAIL_BCC)); // 郵件的密送人
    message.setSubject("Subject"); 
    message.setText("Content");
 
    ts.sendMessage(message, message.getAllRecipients());
    ts.close();
}

發(fā)送HTML郵件

public static void main(String[] args) throws Exception {
    Properties prop = new Properties();
    ... ... // Set properties
    Session session = Session.getInstance(prop); 
    Transport ts = session.getTransport();

    MimeMessage message = new MimeMessage(session);
    ... ... // Head of Message.
    
    String htmlContent = "<h1>Hello</h1>" + "<p>顯示圖片<img src='cid:abc.jpg'>1.jpg</p>";
    MimeBodyPart text = new MimeBodyPart();
    text.setContent(htmlContent, "text/html;charset=UTF-8");
    MimeBodyPart image = new MimeBodyPart();
    DataHandler dh = new DataHandler(new FileDataSource("D://img.jpg"));
    image.setDataHandler(dh);
    image.setContentID("image.jpg");

    MimeMultipart mm = new MimeMultipart();
    mm.addBodyPart(text); 
    mm.addBodyPart(image);
    mm.setSubType("related");
    message.setContent(mm);
    message.saveChanges();

    ts.sendMessage(message, message.getAllRecipients());
    ts.close();
}

發(fā)送帶附件的郵件

public static void main(String[] args) throws Exception {
    ... ...
    MimeBodyPart text = new MimeBodyPart();
    text.setContent("郵件中有兩個附件。", "text/html;charset=UTF-8");

    MimeMultipart mm = new MimeMultipart();
    mm.setSubType("related");
    mm.addBodyPart(text);

    String[] files = {"D://[04]Temp//img//1.jpg", "D://[04]Temp//img//2.jpg"};
    for(String filename : files) {
        MimeBodyPart attachPart = new MimeBodyPart();
        attachPart.attachFile(filename);  
        mm.addBodyPart(attachPart);
    }
    message.setContent(mm);
    message.saveChanges();
    ... ...
}

獲取郵箱中的郵件

public class StoreMail {
    final static String USER = "robot"; // 用戶名
    final static String PASSWORD = "password520"; // 密碼
    public final static String MAIL_SERVER_HOST = "mail.***.com"; // 郵箱服務(wù)器
    public final static String TYPE_HTML = "text/html;charset=UTF-8"; // 文本內(nèi)容類型
    public final static String MAIL_FROM = "[email protected]"; // 發(fā)件人
    public final static String MAIL_TO = "[email protected]"; // 收件人
    public final static String MAIL_CC = "[email protected]"; // 抄送人
    public final static String MAIL_BCC = "[email protected]"; // 密送人

    public static void main(String[] args) throws Exception {
        // 創(chuàng)建一個有具體連接信息的Properties對象
        Properties prop = new Properties();
        prop.setProperty("mail.debug", "true");
        prop.setProperty("mail.store.protocol", "pop3");
        prop.setProperty("mail.pop3.host", MAIL_SERVER_HOST);
        // 1、創(chuàng)建session
        Session session = Session.getInstance(prop);
        // 2、通過session得到Store對象
        Store store = session.getStore();
        // 3、連上郵件服務(wù)器
        store.connect(MAIL_SERVER_HOST, USER, PASSWORD);
        // 4、獲得郵箱內(nèi)的郵件夾
        Folder folder = store.getFolder("inbox");
        folder.open(Folder.READ_ONLY);
        // 獲得郵件夾Folder內(nèi)的所有郵件Message對象
        Message[] messages = folder.getMessages();
        for (int i = 0; i < messages.length; i++) {
            String subject = messages[i].getSubject();
            String from = (messages[i].getFrom()[0]).toString();
            System.out.println("第 " + (i + 1) + "封郵件的主題:" + subject);
            System.out.println("第 " + (i + 1) + "封郵件的發(fā)件人地址:" + from);
        }
        // 5、關(guān)閉
        folder.close(false);
        store.close();
    }
}

PS:注意

上述小栗子非本人所寫,搬運自這里。大家可以通過這些例子了解Java Mail。

我寫的例子中將Properties、SMTP服務(wù)器、群發(fā)用戶名、要發(fā)送的內(nèi)容等寫入了配置文件中。
這里需要說明的是:由于本人的代碼涉及文件操作以及集合操作等,涉及Java Mail以外的內(nèi)容,不利于理解,所以本文的代碼采用了搬運的方式。

本人的例子主要實現(xiàn)群發(fā)功能,目前還較為簡單(未加入附件等),測試通過了向Gmail/QQ/163郵箱的郵件發(fā)送。如果有需要可以在這里下載源碼。

文件列表說明
users.txt:存放要轉(zhuǎn)發(fā)的用戶名(本人已經(jīng)處理了空行以及注釋#
setting.properties:Session需要的上下文環(huán)境
hosts.properties:配置SMTP服務(wù)器
content.html:本人用于測試的發(fā)送內(nèi)容
src/email/test:一些測試
src/email/joshua/util:用于讀取配置、地址轉(zhuǎn)換的工具
src/email/Sender:完成發(fā)送功能的類
src/email/Main:完成用戶的輸入輸出,運行該類執(zhí)行程序

測試結(jié)果

參考

JAVA MAIL發(fā)送郵件實例
JAVA MAIL實現(xiàn)Email的發(fā)送
JavaMail發(fā)送郵件的最簡單示例

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 228,363評論 6 532
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 98,497評論 3 416
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事。” “怎么了?”我有些...
    開封第一講書人閱讀 176,305評論 0 374
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經(jīng)常有香客問我,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 62,962評論 1 311
  • 正文 為了忘掉前任,我火速辦了婚禮,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當我...
    茶點故事閱讀 71,727評論 6 410
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 55,193評論 1 324
  • 那天,我揣著相機與錄音,去河邊找鬼。 笑死,一個胖子當著我的面吹牛,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 43,257評論 3 441
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 42,411評論 0 288
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 48,945評論 1 335
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 40,777評論 3 354
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 42,978評論 1 369
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 38,519評論 5 359
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 44,216評論 3 347
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 34,642評論 0 26
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 35,878評論 1 286
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個月前我還...
    沈念sama閱讀 51,657評論 3 391
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 47,960評論 2 373

推薦閱讀更多精彩內(nèi)容