使用JavaMail收發(fā)郵件

概述

郵件相關的標準

廠商所提供的 JavaMail 服務程序可以有選擇地實現某些郵件協議占卧,常見的郵件協議包括:

SMTP(Simple Mail Transfer Protocol) :即簡單郵件傳輸協議俘陷,它是一組用于由源地址到目的地址傳送郵件的規(guī)則,由它來控制信件的中轉方式喜德。

POP3(Post Office Protocol - Version 3) :即郵局協議版本 3 ,用于接收電子郵件的標準協議毅糟。

IMAP(Internet Mail Access Protocol) :即 Internet 郵件訪問協議柠并。是 POP3 的替代協議。

這三種協議都有對應 SSL 加密傳輸的協議密幔,分別是 **SMTPS **楔脯, **POP3S **和 **IMAPS **。

MIME(Multipurpose Internet Mail Extensions) :即多用途因特網郵件擴展標準胯甩。它不是郵件傳輸協議昧廷。但對傳輸內容的消息、附件及其它的內容定義了格式偎箫。

JavaMail 簡介

JavaMail 是由 Sun 發(fā)布的用來處理 email 的 API 木柬。它并沒有包含在 Java SE 中,而是作為 Java EE 的一部分淹办。

mail.jar :此 JAR 文件包含 JavaMail API 和 Sun 提供的 SMTP 眉枕、 IMAP 和 POP3 服務提供程序;

activation.jar :此 JAR 文件包含 JAF API 和 Sun 的實現怜森。

JavaMail 包中用于處理電子郵件的核心類是: Properties 速挑、 SessionMessage 塔插、 Address 梗摇、 AuthenticatorTransport 想许、 Store 等伶授。

郵件傳輸過程

如上圖断序,電子郵件的處理步驟如下:

  1. 創(chuàng)建一個 Session 對象。

  2. Session 對象創(chuàng)建一個 Transport 對象 /Store 對象糜烹,用來發(fā)送 / 保存郵件违诗。

  3. Transport 對象 /Store 對象連接郵件服務器。

  4. Transport 對象 /Store 對象創(chuàng)建一個 Message 對象 ( 也就是郵件內容 ) 疮蹦。

  5. Transport 對象發(fā)送郵件诸迟; Store 對象獲取郵箱的郵件。

Message 結構

MimeMessage 類:代表整封郵件愕乎。

MimeBodyPart 類:代表郵件的一個 MIME 信息阵苇。

MimeMultipart 類:代表一個由多個 MIME 信息組合成的組合 MIME 信息。

使用JavaMail收發(fā)郵件0

JavaMail 的核心類

JavaMail 對收發(fā)郵件進行了高級的抽象感论,形成了一些關鍵的的接口和類绅项,它們構成了程序的基礎,下面我們分別來了解一下這些最常見的對象比肄。

java.util.Properties類(屬性對象)

java.util.Properties 類代表一組屬性集合快耿。

它的每一個鍵和值都是 String 類型。

由于 JavaMail 需要和郵件服務器進行通信芳绩,這就要求程序提供許多諸如服務器地址掀亥、端口、用戶名妥色、密碼等信息搪花, JavaMail 通過 Properties 對象封裝這些屬性信息。

例: 如下面的代碼封裝了幾個屬性信息:

Properties prop = new Properties();
prop.setProperty("mail.debug", "true");
prop.setProperty("mail.host", "[email protected]");
prop.setProperty("mail.transport.protocol", "smtp");
prop.setProperty("mail.smtp.auth", "true");

針對不同的的郵件協議垛膝, JavaMail 規(guī)定了服務提供者必須支持一系列屬性鳍侣,

下表是一些常見屬性(屬性值都以 String 類型進行設置丁稀,屬性類型欄僅表示屬性是如何被解析的):

關鍵詞 類型 描述
mail.debug boolean debug 開關吼拥。
mail.host String 指定發(fā)送、接收郵件的默認郵箱服務器线衫。
mail.store.protocol String 指定接收郵件的協議凿可。
mail.transport.protocol String 指定發(fā)送郵件的協議。
mail.debug.auth boolean debug 輸出中是否包含認證命令授账。默認是 false 枯跑。

詳情請參考官方 API 文檔:

https://javamail.java.net/nonav/docs/api/

javax.mail.Session類(會話對象)

Session 表示一個郵件會話白热。

Session 的主要作用包括兩個方面:

  • 接收各種配置屬性信息:通過 Properties 對象設置的屬性信息敛助;

  • 初始化 JavaMail 環(huán)境:根據 JavaMail 的配置文件,初始化 JavaMail 環(huán)境屋确,以便通過 Session 對象創(chuàng)建其他重要類的實例纳击。

JavaMail 在 Jar 包的 META-INF 目錄下续扔,通過以下文件提供了基本配置信息,以便 session 能夠根據這個配置文件加載提供者的實現類:

  • javamail.default.providers

  • javamail.default.address.map

Paste_Image.png

例:

Properties props = new Properties();
props.setProperty("mail.transport.protocol", "smtp");
Session session = Session.getInstance(props);

javax.mail.Transport類(郵件傳輸)

郵件操作只有發(fā)送或接收兩種處理方式焕数。

JavaMail 將這兩種不同操作描述為傳輸( javax.mail.Transport )和存儲( javax.mail.Store )纱昧,傳輸對應郵件的發(fā)送,而存儲對應郵件的接收堡赔。

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

connect **: **如果設置了認證命令—— mail.smtp.auth 善已,那么使用 Transport 類的 connect 方法連接服務器時灼捂,則必須加上用戶名和密碼。

sendMessage : Transport 類的 sendMessage 方法用來發(fā)送郵件消息换团。

close : Transport 類的 close 方法用來關閉和郵件服務器的連接纵东。

javax.mail.Store 類(郵件存儲 )

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

connect : 如果設置了認證命令—— mail.smtp.auth 偎球,那么使用 Store 類的 connect 方法連接服務器時,則必須加上用戶名和密碼辑甜。

getFolder:Store 類的 getFolder 方法可以 獲取郵箱內的郵件夾 Folder 對象

close : Store 類的 close 方法用來關閉和郵件服務器的連接衰絮。

javax.mail.Message類(消息對象)

javax.mail.Message 是個抽象類,只能用子類去實例化磷醋,多數情況下為 javax.mail.internet.MimeMessage猫牡。

MimeMessage 代表 MIME 類型的電子郵件消息。

要創(chuàng)建一個 Message 邓线,需要將 Session 對象傳遞給 MimeMessage 構造器:

MimeMessage message = new MimeMessage(session);

注意:還存在其它構造器淌友,如用按 RFC822 格式的輸入流來創(chuàng)建消息。

setFrom :設置郵件的發(fā)件人

setRecipient :設置郵件的發(fā)送人骇陈、抄送人震庭、密送人

三種預定義的地址類型是:

Message.RecipientType.TO :收件人

Message.RecipientType.CC :抄送人

Message.RecipientType.BCC :密送人

setSubject :設置郵件的主題

setContent :設置郵件內容

setText :如果郵件內容是純文本,可以使用此接口設置文本內容你雌。

javax.mail.Address類(地址)

一旦您創(chuàng)建了 Session 和 Message 器联,并將內容填入消息后,就可以用 Address 確定信件地址了婿崭。和 Message 一樣拨拓, Address 也是個抽象類。您用的是 javax.mail.internet.InternetAddress 類氓栈。

若創(chuàng)建的地址只包含電子郵件地址渣磷,只要傳遞電子郵件地址到構造器就行了圈盔。

例:

Address address = new InternetAddress("[email protected]");

Authenticator類(認證者)

與 java.net 類一樣杭跪, JavaMail API 也可以利用 Authenticator 通過用戶名和密碼訪問受保護的資源漓柑。對于 JavaMail API 來說坡脐,這些資源就是郵件服務器。Authenticator 在 javax.mail 包中物独,而且它和 java.net 中同名的類 Authenticator 不同袜硫。兩者并不共享同一個 Authenticator ,因為 JavaMail API 用于 Java 1.1 挡篓,它沒有 java.net 類別婉陷。

要使用 Authenticator ,先創(chuàng)建一個抽象類的子類官研,并從 getPasswordAuthentication() 方法中返回 PasswordAuthentication 實例秽澳。創(chuàng)建完成后,您必需向 session 注冊 Authenticator 戏羽。然后担神,在需要認證的時候,就會通知 Authenticator 始花。您可以彈出窗口妄讯,也可以從配置文件中(雖然沒有加密是不安全的)讀取用戶名和密碼,將它們作為 PasswordAuthentication 對象返回給調用程序酷宵。

例:

Properties props = new Properties();
Authenticator auth = new MyAuthenticator();
Session session = Session.getDefaultInstance(props, auth);

實例

發(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");

    // 1亥贸、創(chuàng)建session
    Session session = Session.getInstance(prop);
    Transport ts = null;

    // 2、通過session得到transport對象
    ts = session.getTransport();

    // 3浇垦、連上郵件服務器
    ts.connect(MAIL_SERVER_HOST, USER, PASSWORD);

    // 4炕置、創(chuàng)建郵件
    MimeMessage message = new MimeMessage(session);

    // 郵件消息頭
    message.setFrom(new InternetAddress(MAIL_FROM)); // 郵件的發(fā)件人
    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("測試文本郵件"); // 郵件的標題

    // 郵件消息體
    message.setText("天下無雙。");

    // 5男韧、發(fā)送郵件
    ts.sendMessage(message, message.getAllRecipients());
    ts.close();
}

發(fā)送 HTML 格式的郵件

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");

    // 1朴摊、創(chuàng)建session
    Session session = Session.getInstance(prop);
    Transport ts = null;

    // 2、通過session得到transport對象
    ts = session.getTransport();

    // 3此虑、連上郵件服務器
    ts.connect(MAIL_SERVER_HOST, USER, PASSWORD);

    // 4甚纲、創(chuàng)建郵件
    MimeMessage message = new MimeMessage(session);

    // 郵件消息頭
    message.setFrom(new InternetAddress(MAIL_FROM)); // 郵件的發(fā)件人
    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("測試HTML郵件"); // 郵件的標題

    String htmlContent = "<h1>Hello</h1>" + "<p>顯示圖片![](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:\\05_Datas\\圖庫\\吉他少年背影.png"));
    image.setDataHandler(dh);
    image.setContentID("abc.jpg");

    // 描述數據關系
    MimeMultipart mm = new MimeMultipart();
    mm.addBodyPart(text);
    mm.addBodyPart(image);
    mm.setSubType("related");
    message.setContent(mm);
    message.saveChanges();

    // 5、發(fā)送郵件
    ts.sendMessage(message, message.getAllRecipients());
    ts.close();
}

發(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");

    // 1寡壮、創(chuàng)建session
    Session session = Session.getInstance(prop);

    // 2贩疙、通過session得到transport對象
    Transport ts = session.getTransport();

    // 3讹弯、連上郵件服務器
    ts.connect(MAIL_SERVER_HOST, USER, PASSWORD);

    // 4况既、創(chuàng)建郵件
    MimeMessage message = new MimeMessage(session);

    // 郵件消息頭
    message.setFrom(new InternetAddress(MAIL_FROM)); // 郵件的發(fā)件人
    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("測試帶附件郵件"); // 郵件的標題

    MimeBodyPart text = new MimeBodyPart();
    text.setContent("郵件中有兩個附件。", "text/html;charset=UTF-8");

    // 描述數據關系
    MimeMultipart mm = new MimeMultipart();
    mm.setSubType("related");
    mm.addBodyPart(text);
    String[] files = {
            "D:\\00_Temp\\temp\\1.jpg", "D:\\00_Temp\\temp\\2.png"
    };

    // 添加郵件附件
    for (String filename : files) {
        MimeBodyPart attachPart = new MimeBodyPart();
        attachPart.attachFile(filename);
        mm.addBodyPart(attachPart);
    }

    message.setContent(mm);
    message.saveChanges();

    // 5组民、發(fā)送郵件
    ts.sendMessage(message, message.getAllRecipients());
    ts.close();
} 

獲取郵箱中的郵件

 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臭胜、連上郵件服務器
    store.connect(MAIL_SERVER_HOST, USER, PASSWORD);

    // 4莫其、獲得郵箱內的郵件夾
    Folder folder = store.getFolder("inbox");
    folder.open(Folder.READ_ONLY);

    // 獲得郵件夾Folder內的所有郵件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癞尚、關閉
    folder.close(false);
    store.close();
}

轉發(fā)郵件

例:獲取指定郵件夾下的第一封郵件并轉發(fā)

 public static void main(String[] args) throws Exception {
    Properties prop = new Properties();
    prop.put("mail.store.protocol", "pop3");
    prop.put("mail.pop3.host", MAIL_SERVER_POP3);
    prop.put("mail.pop3.starttls.enable", "true");
    prop.put("mail.smtp.auth", "true");
    prop.put("mail.smtp.host", MAIL_SERVER_SMTP);

    // 1、創(chuàng)建session
    Session session = Session.getDefaultInstance(prop);

    // 2乱陡、讀取郵件夾
    Store store = session.getStore("pop3");
    store.connect(MAIL_SERVER_POP3, USER, PASSWORD);
    Folder folder = store.getFolder("inbox");
    folder.open(Folder.READ_ONLY);

    // 獲取郵件夾中第1封郵件信息
    Message[] messages = folder.getMessages();
    if (messages.length <= 0) {
        return;
    }
    Message message = messages[0];

    // 打印郵件關鍵信息
    String from = InternetAddress.toString(message.getFrom());
    if (from != null) {
        System.out.println("From: " + from);
    }

    String replyTo = InternetAddress.toString(message.getReplyTo());
    if (replyTo != null) {
        System.out.println("Reply-to: " + replyTo);
    }

    String to = InternetAddress.toString(message.getRecipients(Message.RecipientType.TO));
    if (to != null) {
        System.out.println("To: " + to);
    }

    String subject = message.getSubject();
    if (subject != null) {
        System.out.println("Subject: " + subject);
    }

    Date sent = message.getSentDate();
    if (sent != null) {
        System.out.println("Sent: " + sent);
    }

    // 設置轉發(fā)郵件信息頭
    Message forward = new MimeMessage(session);
    forward.setFrom(new InternetAddress(MAIL_FROM));
    forward.setRecipient(Message.RecipientType.TO, new InternetAddress(MAIL_TO));
    forward.setSubject("Fwd: " + message.getSubject());

    // 設置轉發(fā)郵件內容
    MimeBodyPart bodyPart = new MimeBodyPart();
    bodyPart.setContent(message, "message/rfc822");

    Multipart multipart = new MimeMultipart();
    multipart.addBodyPart(bodyPart);
    forward.setContent(multipart);
    forward.saveChanges();

    Transport ts = session.getTransport("smtp");
    ts.connect(USER, PASSWORD);
    ts.sendMessage(forward, forward.getAllRecipients());

    folder.close(false);
    store.close();
    ts.close();
    System.out.println("message forwarded successfully....");
}
最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
  • 序言:七十年代末浇揩,一起剝皮案震驚了整個濱河市,隨后出現的幾起案子憨颠,更是在濱河造成了極大的恐慌胳徽,老刑警劉巖,帶你破解...
    沈念sama閱讀 206,723評論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件爽彤,死亡現場離奇詭異养盗,居然都是意外死亡,警方通過查閱死者的電腦和手機适篙,發(fā)現死者居然都...
    沈念sama閱讀 88,485評論 2 382
  • 文/潘曉璐 我一進店門往核,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人嚷节,你說我怎么就攤上這事聂儒。” “怎么了硫痰?”我有些...
    開封第一講書人閱讀 152,998評論 0 344
  • 文/不壞的土叔 我叫張陵薄货,是天一觀的道長。 經常有香客問我碍论,道長谅猾,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 55,323評論 1 279
  • 正文 為了忘掉前任鳍悠,我火速辦了婚禮税娜,結果婚禮上,老公的妹妹穿的比我還像新娘藏研。我一直安慰自己敬矩,他們只是感情好,可當我...
    茶點故事閱讀 64,355評論 5 374
  • 文/花漫 我一把揭開白布蠢挡。 她就那樣靜靜地躺著弧岳,像睡著了一般。 火紅的嫁衣襯著肌膚如雪业踏。 梳的紋絲不亂的頭發(fā)上禽炬,一...
    開封第一講書人閱讀 49,079評論 1 285
  • 那天,我揣著相機與錄音勤家,去河邊找鬼腹尖。 笑死,一個胖子當著我的面吹牛伐脖,可吹牛的內容都是我干的热幔。 我是一名探鬼主播乐设,決...
    沈念sama閱讀 38,389評論 3 400
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼绎巨!你這毒婦竟也來了近尚?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 37,019評論 0 259
  • 序言:老撾萬榮一對情侶失蹤场勤,失蹤者是張志新(化名)和其女友劉穎肿男,沒想到半個月后,有當地人在樹林里發(fā)現了一具尸體却嗡,經...
    沈念sama閱讀 43,519評論 1 300
  • 正文 獨居荒郊野嶺守林人離奇死亡舶沛,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 35,971評論 2 325
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現自己被綠了窗价。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片如庭。...
    茶點故事閱讀 38,100評論 1 333
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖撼港,靈堂內的尸體忽然破棺而出坪它,到底是詐尸還是另有隱情,我是刑警寧澤帝牡,帶...
    沈念sama閱讀 33,738評論 4 324
  • 正文 年R本政府宣布往毡,位于F島的核電站,受9級特大地震影響靶溜,放射性物質發(fā)生泄漏开瞭。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 39,293評論 3 307
  • 文/蒙蒙 一罩息、第九天 我趴在偏房一處隱蔽的房頂上張望嗤详。 院中可真熱鬧,春花似錦瓷炮、人聲如沸葱色。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,289評論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽苍狰。三九已至,卻和暖如春烘绽,著一層夾襖步出監(jiān)牢的瞬間淋昭,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 31,517評論 1 262
  • 我被黑心中介騙來泰國打工诀姚, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留响牛,地道東北人。 一個月前我還...
    沈念sama閱讀 45,547評論 2 354
  • 正文 我出身青樓赫段,卻偏偏與公主長得像呀打,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子糯笙,可洞房花燭夜當晚...
    茶點故事閱讀 42,834評論 2 345

推薦閱讀更多精彩內容

  • 本文包括:1贬丛、名詞解釋2、郵件收發(fā)過程3给涕、JavaMail 知識概要4豺憔、發(fā)送一封符合 MIME 協議的 JavaM...
    廖少少閱讀 3,990評論 2 13
  • Java Mail 簡介 常見的郵件協議包括:SMTP(Simple Mail Transfer Protocol...
    Josaber閱讀 3,265評論 1 9
  • 從三月份找實習到現在,面了一些公司够庙,掛了不少恭应,但最終還是拿到小米、百度耘眨、阿里昼榛、京東、新浪剔难、CVTE胆屿、樂視家的研發(fā)崗...
    時芥藍閱讀 42,192評論 11 349
  • 一、簡述發(fā)送和收取郵件的協議 SMTP 簡單郵件傳輸協議(Simple Mail Transfer Protoco...
    淚催伊人心閱讀 1,163評論 5 4
  • 背景 近期需要實現一個郵件客戶端的項目偶宫,類似Foxmail非迹,outlook客戶端。但項目只做消息轉發(fā)纯趋,不需要完整實...
    BigBug77閱讀 4,270評論 0 4