樂(lè)字節(jié)-Spring 郵件發(fā)送

Spring 郵件發(fā)送

主要內(nèi)容

JavaMail 概述

? JavaMail,顧名思義车伞,提供給開發(fā)者處理電子郵件相關(guān)的編程接口月帝。JavaMail 是由 Sun 定義的一套收發(fā)電子郵件的 API,它可以方便地執(zhí)行一些常用的郵件傳輸拄查,不同的廠商可以提供自己的實(shí)現(xiàn)類豪娜。但它并沒(méi)有包含在 JDK 中餐胀,而是作為 JavaEE 的一部分。

? 廠商所提供的 JavaMail 服務(wù)程序可以有選擇地實(shí)現(xiàn)某些郵件協(xié)議侵歇,常見(jiàn)的郵件協(xié)議包括:

SMTP:簡(jiǎn)單郵件傳輸協(xié)議骂澄,用于發(fā)送電子郵件的傳輸協(xié)議吓蘑;

POP3:用于接收電子郵件的標(biāo)準(zhǔn)協(xié)議惕虑;

IMAP:互聯(lián)網(wǎng)消息協(xié)議,是 POP3 的替代協(xié)議磨镶。

? 這三種協(xié)議都有對(duì)應(yīng) SSL 加密傳輸?shù)膮f(xié)議溃蔫,分別是 SMTPS,POP3S 和 IMAPS琳猫。除 JavaMail 服務(wù)提供程序之外伟叛, JavaMail 還需要 JAF(JavaBeans Activation Framework)來(lái)處理不是純文本的郵件內(nèi)容,這包括 MIME(多用途互聯(lián)網(wǎng)郵件擴(kuò)展)脐嫂、URL 頁(yè)面和文件附件等內(nèi)容统刮。另外紊遵,JavaMail 依賴 JAF(JavaBeans Activation Framework),JAF 在 Java6 之后已經(jīng)合并到 JDK 中侥蒙,而 JDK5 之前需要另外下載 JAF 的類庫(kù)暗膜。

協(xié)議介紹

? 在研究 JavaMail API 的細(xì)則之前,首先需要對(duì)于 API 用到的協(xié)議有個(gè)認(rèn)識(shí)鞭衩。對(duì)于 java mail 來(lái)說(shuō)用到的協(xié)議有常見(jiàn)的幾種: SMTP学搜、POP、IMAP论衍、MIME

SMTP

? 簡(jiǎn)單郵件傳輸協(xié)議(Simple Mail Transfer Protocol瑞佩,SMTP)由 RFC 821 定義。它定義了發(fā)送電子郵件的機(jī)制坯台。在 JavaMail API 環(huán)境中炬丸,您基于 JavaMail 的程序?qū)⒑湍墓净蛞蛱鼐W(wǎng)服務(wù)供應(yīng)商的(Internet Service

Provider’s,ISP’s)SMTP 服務(wù)器通信蜒蕾。SMTP 服務(wù)器會(huì)中轉(zhuǎn)消息給接收方 SMTP 服務(wù)器以便最終讓用戶經(jīng)由 POP 或 IMAP 獲得御雕。

POP

? POP 代表郵局協(xié)議(Post Office Protocol)。目前用的是版本 3滥搭,也稱 POP3酸纲,RFC 1939 定義了這個(gè)協(xié)議。POP 是一種機(jī)制瑟匆,因特網(wǎng)上大多數(shù)人用它得到郵件闽坡。它規(guī)定每個(gè)用戶一個(gè)郵箱的支持。這就是它所能做的愁溜,而這也造成了許多混淆疾嗅。使用 POP3 時(shí),用戶熟悉的許多性能并不是由 POP 協(xié)議支持的冕象,如查看有幾封新郵件消息這一性能代承。這些性能內(nèi)建于如 Eudora 或 Microsoft Outlook 之類的程序中,它們能記住一些事渐扮,諸如最近一次收到的郵件论悴,還能計(jì)算出有多少是新的。所以當(dāng)使用 JavaMail API 時(shí)墓律,如果您想要這類信息膀估,您就必須自己算。

IMAP

? IMAP 是更高級(jí)的用于接收消息的協(xié)議耻讽。在 RFC 2060 中被定義察纯,IMAP 代表因特網(wǎng)消息訪問(wèn)協(xié)議(Internet Message Access Protocol),目前用的是版本 4,也稱 IMAP4饼记。在用到 IMAP 時(shí)香伴,郵件服務(wù)器必需支持這個(gè)協(xié)議。不能僅僅把使用 POP 的程序用于 IMAP具则,并指望它支持 IMAP 所有性能瞒窒。假設(shè)郵件服務(wù)器支持 IMAP,基于 JavaMail 的程序可以利用這種情況 — 用戶在服務(wù)器上有多個(gè)文件夾(folder)乡洼,并且這些文件夾可以被多個(gè)用戶共享崇裁。因?yàn)橛羞@一更高級(jí)的性能,您也許會(huì)認(rèn)為所有用戶都會(huì)使用 IMAP束昵。事實(shí)并不是這樣拔稳。要求服務(wù)器接收新消息,在用戶請(qǐng)求時(shí)發(fā)送到用戶手中锹雏,還要在每個(gè)用戶的多個(gè)文件夾中維護(hù)消息巴比。這樣雖然能將消息集中備份,但隨著用戶長(zhǎng)期的郵件夾越來(lái)越大礁遵,到磁盤空間耗盡時(shí)轻绞,每個(gè)用戶都會(huì)受到損失。使用 POP佣耐,就能卸載郵件服務(wù)器上保存的消息了政勃。

MIME

? MIME 代表多用途因特網(wǎng)郵件擴(kuò)展標(biāo)準(zhǔn)(Multipurpose Internet Mail Extensions)。它不是郵件傳輸協(xié)議兼砖。但對(duì)傳輸內(nèi)容的消息奸远、附件及其它的內(nèi)容定義了格式。這里有很多不同的有效文檔:RFC 822讽挟、RFC 2045懒叛、RFC

2046 和 RFC 2047。作為一個(gè) JavaMail API 的用戶耽梅,您通常不必對(duì)這些格式操心薛窥。無(wú)論如何,一定存在這些格式而且程序會(huì)用到它眼姐。

JavaMail 的關(guān)鍵對(duì)象

? JavaMail 對(duì)收發(fā)郵件進(jìn)行了高級(jí)的抽象诅迷,形成了一些關(guān)鍵的的接口和類,它們構(gòu)成了程序的基礎(chǔ)妥凳,下面我們分別來(lái)了解一下這些最常見(jiàn)的對(duì)象竟贯。

Properties 屬性對(duì)象

? 由于 JavaMail 需要和郵件服務(wù)器進(jìn)行通信,這就要求程序提供許多諸如服務(wù)器地址逝钥、端口、用戶名、密碼等信息艘款,JavaMail 通過(guò) Properties 對(duì)象封裝這些屬性信息持际。如下面的代碼封裝了兩個(gè)屬性信息:

Properties props=newProperties();props.put("mail.smtp.host","smtp.sina.com.cn");props.put("mail.smtp.auth","true");

? 針對(duì)不同的的郵件協(xié)議,JavaMail 規(guī)定了服務(wù)提供者必須支持一系列屬性哗咆,下表是針對(duì) SMTP 協(xié)議的一些常見(jiàn)屬性(屬性值都以 String 類型進(jìn)行設(shè)置蜘欲,屬性類型欄僅表示屬性是如何被解析的):

屬性名類型說(shuō)明

mail.smtp.hostStringSMTP 服務(wù)器地址,如smtp.sina.com.cn

mail.smtp.portintSMTP 服務(wù)器端口號(hào)晌柬,默認(rèn)為 25

mail.smtp.authbooleanSMTP 服務(wù)器是否需要用戶認(rèn)證姥份,默認(rèn)為 false

mail.smtp.userStringSMTP 默認(rèn)的登陸用戶名

mail.smtp.fromString默認(rèn)的郵件發(fā)送源地址

mail.smtp.socketFactory.classStringsocket 工廠類類名

通過(guò)設(shè)置該屬性可以覆蓋提供者默認(rèn)的實(shí)現(xiàn),必須實(shí)現(xiàn)javax.NET.SocketFactory接口

mail.smtp.socketFactory.portint指定 socket 工廠類所用的端口號(hào)

如果沒(méi)有規(guī)定年碘,則使用默認(rèn)的端口號(hào)

mail.smtp.socketFactory.fallbackboolean設(shè)置為 true 時(shí)澈歉,當(dāng)使用指定的socket 類創(chuàng)建 socket 失敗后,將使用 Java.net.Socket 創(chuàng)建socket屿衅,默認(rèn)為 true

mail.smtp.timeoutintI/O 連接超時(shí)時(shí)間埃难,單位為毫秒,默認(rèn)為永不超時(shí)

? 其他幾個(gè)協(xié)議也有類似的一系列屬性涤久,如 POP3 的 mail.pop3.host涡尘、mail.pop3.port 以及IMAP 的 mail.imap.host、mail.imap.host 等响迂。

Session 會(huì)話對(duì)象

? Session 是一個(gè)很容易被誤解的類考抄,這歸咎于混淆視聽的類名。千萬(wàn)不要以為這里的 Session 像 HttpSession 一樣代表真實(shí)的交互會(huì)話蔗彤,但創(chuàng)建 Session 對(duì)象時(shí)座泳,并沒(méi)有對(duì)應(yīng)的物理連接,它只不過(guò)是一對(duì)配置信息的集合幕与。

? Session 的主要作用挑势,包括兩個(gè)方面:

接收各種配置屬性信息:通過(guò) Properties 對(duì)象設(shè)置的屬性信息;

初始化 JavaMail 環(huán)境:根據(jù) JavaMail 的配置文件啦鸣,初始化 JavaMail 環(huán)境潮饱,以便通過(guò) Session 對(duì)象創(chuàng)建其他重要類的實(shí)例。

Transport 和 Store 傳輸和存儲(chǔ)

? 郵件操作只有發(fā)送或接收兩種處理方式诫给,JavaMail 將這兩種不同操作描述為傳輸(javax.mail.Transport)和存儲(chǔ)(javax.mail.Store)香拉,傳輸對(duì)應(yīng)郵件的發(fā)送,而存儲(chǔ)對(duì)應(yīng)郵件的接收中狂。

Message 消息對(duì)象

? 一旦獲得 Session 對(duì)象凫碌,就可以繼續(xù)創(chuàng)建要發(fā)送的消息。這由 Message 類來(lái)完成胃榕。因?yàn)?Message 是個(gè)抽象類盛险,您必需用一個(gè)子類,多數(shù)情況下為 javax.mail.internet.MimeMessage。MimeMessage 是個(gè)能理解 MIME 類型和頭的電子郵件消息苦掘,正如不同 RFC 中所定義的换帜。雖然在某些頭部域非 ASCII 字符也能被譯碼,但 Message 頭只能被限制為用 US-ASCII 字符鹤啡。

Address 地址

? 一旦您創(chuàng)建了 Session 和 Message惯驼,并將內(nèi)容填入消息后,就可以用 Address 確定信件地址了递瑰。和 Message 一樣祟牲,Address 也是個(gè)抽象類。您用的是 javax.mail.internet.InternetAddress 類抖部。若創(chuàng)建的地址只包含電子郵件地址说贝,只要傳遞電子郵件地址到構(gòu)造器就行了。

Authenticator 認(rèn)證者

? 與 java 類一樣您朽,JavaMail API 也可以利用 Authenticator 通過(guò)用戶名和密碼訪問(wèn)受保護(hù)的資源狂丝。對(duì)于 JavaMail API 來(lái)說(shuō),這些資源就是郵件服務(wù)器哗总。JavaMail Authenticator 在 javax.mail 包中几颜,而且它和 java.net 中同名的類 Authenticator 不同。兩者并不共享同一個(gè) Authenticator讯屈,因?yàn)?JavaMail API 用于 Java 1.1蛋哭,它沒(méi)有 java.net 類別。要使用 Authenticator涮母,先創(chuàng)建一個(gè)抽象類的子類谆趾,并從 getPasswordAuthentication() 方法中返回 PasswordAuthentication 實(shí)例。創(chuàng)建完成后叛本,您必需向 session 注冊(cè) Authenticator沪蓬。然后,在需要認(rèn)證的時(shí)候来候,就會(huì)通知 Authenticator跷叉。您可以彈出窗口,也可以從配置文件中(雖然沒(méi)有加密是不安全的)讀取用戶名和密碼营搅,將它們作為 PasswordAuthentication 對(duì)象返回給調(diào)用程序云挟。

Java Mail 環(huán)境準(zhǔn)備

設(shè)置郵箱服務(wù)

這里是以163郵箱為例

注冊(cè) 163 郵箱,登錄 163 郵箱后转质,設(shè)置郵箱賬戶開通 smtp 服務(wù)

? 需要根據(jù)注冊(cè)時(shí)的手機(jī)號(hào)發(fā)送的驗(yàn)證碼來(lái)開通獲取郵箱客戶端授權(quán)碼园欣。開通成功后,會(huì)顯示個(gè)人授權(quán)訪問(wèn)碼休蟹,該授權(quán)碼是后面通過(guò) Java mail 發(fā)送郵件的認(rèn)證密碼沸枯,非常重要日矫。

添加依賴

創(chuàng)建 Maven 項(xiàng)目,在 pom.xml 配置文件中添加 mail 的所需的依賴

<!-- Java Mail --><dependency><groupId>com.sun.mail</groupId><artifactId>javax.mail</artifactId><version>1.6.2</version></dependency><dependency><groupId>javax.mail</groupId><artifactId>javax.mail-api</artifactId><version>1.6.2</version></dependency>

Java Mail 發(fā)送郵件

發(fā)送普通文本的郵件

packagecom.xxxx.mail;importjavax.activation.DataHandler;importjavax.activation.FileDataSource;importjavax.mail.*;importjavax.mail.internet.*;importjava.io.UnsupportedEncodingException;importjava.util.Date;importjava.util.Properties;/**

* 發(fā)送普通文本的郵件

*/publicclassMailTest01{publicstaticvoidmain(String[]args)throwsException{// 定義郵箱服務(wù)器配置Properties prop=newProperties();// 設(shè)置郵件服務(wù)器主機(jī)名 (163 郵件服務(wù)器地址:"mail.smtp.host"? "smtp.163.com")prop.setProperty("mail.smtp.host","smtp.163.com");// 設(shè)置郵件服務(wù)器的端口prop.setProperty("mail.smtp.port","25");// 設(shè)置郵件服務(wù)器認(rèn)證屬性 (設(shè)置為true表示發(fā)送服務(wù)器需要身份驗(yàn)證)prop.setProperty("mail.smtp.auth","true");// 某些郵箱服務(wù)器要求 SMTP 連接需要使用 SSL 安全認(rèn)證// prop.setProperty("mail.smtp.port", "465");// prop.setProperty("mail.smtp.socketFactory.class", "javax.net.ssl.SSLSocketFactory");// prop.setProperty("mail.smtp.socketFactory.fallback", "false");// prop.setProperty("mail.smtp.socketFactory.port", "465");// 使用JavaMail發(fā)送郵件的5個(gè)步驟// 1. 創(chuàng)建sessionSession session=Session.getInstance(prop);// 開啟Session的debug模式辉饱,這樣就可以查看到程序發(fā)送Email的運(yùn)行狀態(tài)session.setDebug(true);// 2. 通過(guò)session得到transport對(duì)象Transport ts=session.getTransport();// 3. 使用郵箱的用戶名和密碼連上郵件服務(wù)器(用戶名只需寫@前面的即可搬男,密碼是指授權(quán)碼)ts.connect("smtp.163.com","用戶名","密碼");// 4. 創(chuàng)建郵件// 發(fā)送普通文本的郵件Message message=createSimpleTxtMail(session);// 5. 發(fā)送郵件ts.sendMessage(message,message.getAllRecipients());// 關(guān)閉transport對(duì)象ts.close();}/**

? ? * 普通文本郵件

? ? *? ? ? 創(chuàng)建一封只包含文本的郵件

? ? * @param session

? ? * @return

? ? */publicstaticMimeMessagecreateSimpleTxtMail(Session session)throwsMessagingException{// 創(chuàng)建郵件對(duì)象MimeMessage message=newMimeMessage(session);// 設(shè)置郵件的發(fā)件人的郵箱地址message.setFrom(newInternetAddress("發(fā)件人的郵箱地址"));// 設(shè)置郵件的收件人的郵箱地址 (現(xiàn)在發(fā)件人和收件人是一樣的拣展,那就是自己給自己發(fā))message.setRecipient(Message.RecipientType.TO,newInternetAddress("收件人的郵箱地址"));// 發(fā)送給多個(gè)收件人// message.setRecipients(Message.RecipientType.TO, new InternetAddress[] {});// Cc: 抄送(可選)// message.setRecipient(MimeMessage.RecipientType.CC, new InternetAddress(""));// Bcc: 密送(可選)// message.setRecipient(MimeMessage.RecipientType.BCC, new InternetAddress(""));// 郵件的主題message.setSubject("測(cè)試文本郵件");// 設(shè)置發(fā)送日期message.setSentDate(newDate());// 郵件的文本內(nèi)容 (setText():純文本內(nèi)容)message.setText("你好彭沼,這是一封測(cè)試郵件!");// 返回創(chuàng)建好的郵件對(duì)象returnmessage;}}

效果如下:

發(fā)送HTML內(nèi)容的郵件

packagecom.xxxx.mail;importjavax.activation.DataHandler;importjavax.activation.FileDataSource;importjavax.mail.Message;importjavax.mail.MessagingException;importjavax.mail.Session;importjavax.mail.Transport;importjavax.mail.internet.InternetAddress;importjavax.mail.internet.MimeBodyPart;importjavax.mail.internet.MimeMessage;importjavax.mail.internet.MimeMultipart;importjava.util.Date;importjava.util.Properties;/**

* 發(fā)送HTML內(nèi)容的郵件

*/publicclassMailTest02{publicstaticvoidmain(String[]args)throwsException{// 定義郵箱服務(wù)器配置Properties prop=newProperties();// 設(shè)置郵件服務(wù)器主機(jī)名 (163 郵件服務(wù)器地址:"mail.smtp.host"? "smtp.163.com")prop.setProperty("mail.smtp.host","smtp.163.com");// 設(shè)置郵件服務(wù)器的端口prop.setProperty("mail.smtp.port","25");// 設(shè)置郵件服務(wù)器認(rèn)證屬性 (設(shè)置為true表示發(fā)送服務(wù)器需要身份驗(yàn)證)prop.setProperty("mail.smtp.auth","true");// 使用JavaMail發(fā)送郵件的5個(gè)步驟// 1. 創(chuàng)建sessionSession session=Session.getInstance(prop);// 開啟Session的debug模式备埃,這樣就可以查看到程序發(fā)送Email的運(yùn)行狀態(tài)session.setDebug(true);// 2. 通過(guò)session得到transport對(duì)象Transport ts=session.getTransport();// 3. 使用郵箱的用戶名和密碼連上郵件服務(wù)器(用戶名只需寫@前面的即可姓惑,密碼是指授權(quán)碼)ts.connect("smtp.163.com","用戶名","密碼");// 4. 創(chuàng)建郵件// 發(fā)送HTML內(nèi)容的郵件Message message=createHtmlMail(session);// 5. 發(fā)送郵件ts.sendMessage(message,message.getAllRecipients());// 關(guān)閉transport對(duì)象ts.close();}/**

? ? * HTML內(nèi)容郵件

? ? *? ? ? 創(chuàng)建一封包含html內(nèi)容的郵件

? ? */publicstaticMimeMessagecreateHtmlMail(Session session)throwsException{// 創(chuàng)建郵件對(duì)象MimeMessage message=newMimeMessage(session);// 設(shè)置郵件的發(fā)件人的郵箱地址message.setFrom(newInternetAddress("發(fā)件人的郵箱地址"));// 設(shè)置郵件的收件人的郵箱地址 (現(xiàn)在發(fā)件人和收件人是一樣的,那就是自己給自己發(fā))message.setRecipient(Message.RecipientType.TO,newInternetAddress("收件人的郵箱地址"));// 郵件的主題message.setSubject("測(cè)試HTML郵件");// 設(shè)置發(fā)送日期message.setSentDate(newDate());// 準(zhǔn)備郵件數(shù)據(jù)/**

? ? ? ? * Message表示一個(gè)郵件按脚,messgaes.getContent()返回一個(gè)Multipart對(duì)象于毙。

? ? ? ? * 一個(gè)Multipart對(duì)象包含一個(gè)或多個(gè)BodyPart對(duì)象,來(lái)組成郵件的正文部分(包括附件)辅搬。

? ? ? ? */// 創(chuàng)建多媒體對(duì)象MimeMultipart multipart=newMimeMultipart();// 創(chuàng)建郵件體對(duì)象MimeBodyPart bodyPart=newMimeBodyPart();// 設(shè)置HTML內(nèi)容StringBuffer sb=newStringBuffer();sb.append("<html><body><a );// 將bodyPart對(duì)象設(shè)置到multipart對(duì)象中multipart.addBodyPart(bodyPart);// 將multipart對(duì)象設(shè)置到message對(duì)象中 (setContent():)message.setContent(multipart);// 返回創(chuàng)建好的郵件對(duì)象returnmessage;}}

效果如下:

發(fā)送包含附件的郵件

packagecom.xxxx.mail;importjavax.activation.DataHandler;importjavax.activation.FileDataSource;importjavax.mail.Message;importjavax.mail.MessagingException;importjavax.mail.Session;importjavax.mail.Transport;importjavax.mail.internet.InternetAddress;importjavax.mail.internet.MimeBodyPart;importjavax.mail.internet.MimeMessage;importjavax.mail.internet.MimeMultipart;importjava.util.Date;importjava.util.Properties;/**

* 發(fā)送包含附件的郵件

*/publicclassMailTest03{publicstaticvoidmain(String[]args)throwsException{// 定義郵箱服務(wù)器配置Properties prop=newProperties();// 設(shè)置郵件服務(wù)器主機(jī)名 (163 郵件服務(wù)器地址:"mail.smtp.host"? "smtp.163.com")prop.setProperty("mail.smtp.host","smtp.163.com");// 設(shè)置郵件服務(wù)器的端口prop.setProperty("mail.smtp.port","25");// 設(shè)置郵件服務(wù)器認(rèn)證屬性 (設(shè)置為true表示發(fā)送服務(wù)器需要身份驗(yàn)證)prop.setProperty("mail.smtp.auth","true");// 使用JavaMail發(fā)送郵件的5個(gè)步驟// 1. 創(chuàng)建sessionSession session=Session.getInstance(prop);// 開啟Session的debug模式唯沮,這樣就可以查看到程序發(fā)送Email的運(yùn)行狀態(tài)session.setDebug(true);// 2. 通過(guò)session得到transport對(duì)象Transport ts=session.getTransport();// 3. 使用郵箱的用戶名和密碼連上郵件服務(wù)器(用戶名只需寫@前面的即可,密碼是指授權(quán)碼)ts.connect("smtp.163.com","用戶名","密碼");// 4. 創(chuàng)建郵件// 發(fā)送包含附件的郵件Message message=createAttachMail(session);// 5. 發(fā)送郵件ts.sendMessage(message,message.getAllRecipients());// 關(guān)閉transport對(duì)象ts.close();}/**

? ? * 包含附件的郵件

? ? *? ? ? 創(chuàng)建一封包含附件的郵件

? ? * @param session

? ? * @return

? ? * @throws MessagingException

? ? */publicstaticMimeMessagecreateAttachMail(Session session)throwsMessagingException{// 創(chuàng)建郵件對(duì)象MimeMessage message=newMimeMessage(session);// 設(shè)置郵件的發(fā)件人的郵箱地址message.setFrom(newInternetAddress("發(fā)件人的郵箱地址"));// 設(shè)置郵件的收件人的郵箱地址 (現(xiàn)在發(fā)件人和收件人是一樣的堪遂,那就是自己給自己發(fā))message.setRecipient(Message.RecipientType.TO,newInternetAddress("收件人的郵箱地址"));// 郵件的主題message.setSubject("測(cè)試包含附件的郵件");// 設(shè)置發(fā)送日期message.setSentDate(newDate());// 創(chuàng)建郵件正文MimeBodyPart bodyPart=newMimeBodyPart();bodyPart.setContent("使用JavaMail創(chuàng)建的帶附件的郵件","text/html;charset=UTF-8");// 創(chuàng)建附件MimeBodyPart attachPart=newMimeBodyPart();// 本地文件DataHandler dh=newDataHandler(newFileDataSource("C:\\work\\郵件附件.txt"));attachPart.setDataHandler(dh);// 附件名attachPart.setFileName(dh.getName());// 創(chuàng)建容器描述數(shù)據(jù)關(guān)系MimeMultipart multipart=newMimeMultipart();// 添加正文multipart.addBodyPart(bodyPart);// 添加附件multipart.addBodyPart(attachPart);// 如果在郵件中要添加附件介蛉,設(shè)置為mixed;溶褪。multipart.setSubType("mixed");// 設(shè)置郵件的內(nèi)容message.setContent(multipart);// 返回創(chuàng)建好的郵件對(duì)象returnmessage;}}

效果如下:

Java Mail 郵件發(fā)送封裝

創(chuàng)建郵件發(fā)送信息類

packagecom.xxxx.mail;importjava.util.List;/**

* 郵件發(fā)送信息類

*? 定義發(fā)送郵件時(shí) 郵件服務(wù)器 端口 發(fā)送方用戶名 密碼等字段

*/publicclassMailSendInfo{privateString serverHost;// 服務(wù)器主機(jī)privateString serverPort;// 服務(wù)器端口privateString fromAddress;// 發(fā)送方郵箱地址privateList<String>toAddress;// 接收方郵箱地址privateString userName;// 郵件服務(wù)器用戶名privateString userPwd;// 郵件服務(wù)器密碼(授權(quán)密碼)privateString subject;// 郵件主題privateString content;// 郵件內(nèi)容privateBoolean flag=true;// 是否需要身份認(rèn)證privateList<String>attachFileNames;// 附件文件名publicBooleangetFlag(){returnflag;}publicvoidsetFlag(Boolean flag){this.flag=flag;}publicStringgetServerHost(){returnserverHost;}publicvoidsetServerHost(String serverHost){this.serverHost=serverHost;}publicStringgetServerPort(){returnserverPort;}publicvoidsetServerPort(String serverPort){this.serverPort=serverPort;}publicStringgetFromAddress(){returnfromAddress;}publicvoidsetFromAddress(String fromAddress){this.fromAddress=fromAddress;}publicList<String>getToAddress(){returntoAddress;}publicvoidsetToAddress(List<String>toAddress){this.toAddress=toAddress;}publicStringgetUserName(){returnuserName;}publicvoidsetUserName(String userName){this.userName=userName;}publicStringgetUserPwd(){returnuserPwd;}publicvoidsetUserPwd(String userPwd){this.userPwd=userPwd;}publicStringgetSubject(){returnsubject;}publicvoidsetSubject(String subject){this.subject=subject;}publicStringgetContent(){returncontent;}publicvoidsetContent(String content){this.content=content;}publicList<String>getAttachFileNames(){returnattachFileNames;}publicvoidsetAttachFileNames(List<String>attachFileNames){this.attachFileNames=attachFileNames;}}

創(chuàng)建認(rèn)證類

packagecom.xxxx.mail;importjavax.mail.Authenticator;importjavax.mail.PasswordAuthentication;/**

* 認(rèn)證類

*/publicclassMyAuthenticatorextendsAuthenticator{privateString userName;// 郵箱privateString userPwd;// 密碼(授權(quán)碼)publicMyAuthenticator(String userName,String userPwd){this.userName=userName;this.userPwd=userPwd;}/**

? ? * 郵件服務(wù)器發(fā)送郵件時(shí)币旧,進(jìn)行身份驗(yàn)證

? ? * @return

? ? */@OverrideprotectedPasswordAuthenticationgetPasswordAuthentication(){returnnewPasswordAuthentication(userName,userPwd);}}

創(chuàng)建郵件發(fā)送器

packagecom.xxxx.mail;importjavax.activation.DataHandler;importjavax.activation.FileDataSource;importjavax.mail.*;importjavax.mail.internet.*;importjava.io.File;importjava.util.Date;importjava.util.List;importjava.util.Properties;publicclassMailSender{publicvoidsendMail(MailSendInfo mailSendInfo){Message message=null;Session session=null;try{// 定義郵箱服務(wù)器配置Properties props=newProperties();// 163 郵件服務(wù)器地址props.put("mail.smtp.host",mailSendInfo.getServerHost());// 163 郵件服務(wù)器端口props.put("mail.smtp.port",mailSendInfo.getServerPort());// 163 郵件服務(wù)器認(rèn)證屬性props.put("mail.smtp.auth",mailSendInfo.getFlag());// 身份認(rèn)證類MyAuthenticator authenticator=newMyAuthenticator(mailSendInfo.getUserName(),mailSendInfo.getUserPwd());// 創(chuàng)建sessionsession=Session.getDefaultInstance(props,authenticator);// 開啟Session的debug模式,這樣就可以查看到程序發(fā)送Email的運(yùn)行狀態(tài)session.setDebug(true);// 創(chuàng)建message郵件對(duì)象message=newMimeMessage(session);// 設(shè)置發(fā)送方的郵箱地址Address from=newInternetAddress(mailSendInfo.getFromAddress());message.setFrom(from);// 設(shè)置發(fā)送時(shí)間message.setSentDate(newDate());// 判斷接收方的郵箱地址if(null!=mailSendInfo.getToAddress()&&mailSendInfo.getToAddress().size()>0){// 定義數(shù)組Address[]addresses=newAddress[mailSendInfo.getToAddress().size()];// 循環(huán)獲取接收方的郵箱地址猿妈,并設(shè)置到對(duì)應(yīng)的address數(shù)組中for(inti=0;i<mailSendInfo.getToAddress().size();i++){Address address=newInternetAddress(mailSendInfo.getToAddress().get(i));addresses[i]=address;}// 設(shè)置接收方的郵箱地址message.setRecipients(Message.RecipientType.TO,addresses);// 設(shè)置郵件主題message.setSubject(mailSendInfo.getSubject());// 創(chuàng)建多媒體對(duì)象容器Multipart multipart=newMimeMultipart();// 創(chuàng)建正文內(nèi)容BodyPart bodyPart=newMimeBodyPart();bodyPart.setContent(mailSendInfo.getContent(),"text/html;charset=utf-8");// 添加正文 (將正文內(nèi)容設(shè)置到多媒體對(duì)象容器中)multipart.addBodyPart(bodyPart);// 獲取所有的附件內(nèi)容List<String>files=mailSendInfo.getAttachFileNames();// 判斷是否包含附件內(nèi)容if(null!=files&&files.size()>0){for(inti=0;i<files.size();i++){// 獲取對(duì)應(yīng)的附件對(duì)象File tempFile=newFile(files.get(i));// 判斷附件是否存在if(tempFile.exists()){// 如果附件存在吹菱,創(chuàng)建附件對(duì)象BodyPart attachPart=newMimeBodyPart();attachPart.setDataHandler(newDataHandler(newFileDataSource(tempFile)));// 設(shè)置文件名 (解決附件名亂碼)attachPart.setFileName(MimeUtility.encodeText(tempFile.getName()));// 添加附件 (將附件內(nèi)容添加到多媒體對(duì)象容器中)multipart.addBodyPart(attachPart);}}}// 設(shè)置郵件內(nèi)容message.setContent(multipart);// 發(fā)送郵件Transport.send(message);}}catch(Exceptione){e.printStackTrace();}}}

郵件發(fā)送測(cè)試

發(fā)送HTML內(nèi)容的郵件

/**

? * 發(fā)送HTML內(nèi)容的郵件

? */publicstaticvoidtestHtmlMail(){MailSendInfo mailSendInfo=newMailSendInfo();mailSendInfo.setServerHost("smtp.163.com");mailSendInfo.setServerPort("25");mailSendInfo.setUserName("郵箱用戶名");mailSendInfo.setUserPwd("密碼(授權(quán)碼)");mailSendInfo.setSubject("郵件封裝");mailSendInfo.setFromAddress("發(fā)件人的郵箱地址");mailSendInfo.setContent("<h2>這是封裝后發(fā)送的郵件</h2>");List<String>users=newArrayList<>();users.add("收件人的郵箱地址");mailSendInfo.setToAddress(users);MailSender mailSender=newMailSender();mailSender.sendMail(mailSendInfo);}

效果如下:

發(fā)送包含附件的郵件

/**

? * 發(fā)送包含附件的郵件

? */publicstaticvoidtestAttachMail(){MailSendInfo mailSendInfo=newMailSendInfo();mailSendInfo.setServerHost("smtp.163.com");mailSendInfo.setServerPort("25");mailSendInfo.setUserName("用戶名");mailSendInfo.setUserPwd("密碼(授權(quán)碼)");mailSendInfo.setSubject("郵件封裝");mailSendInfo.setFromAddress("發(fā)件人的郵箱地址");mailSendInfo.setContent("<h2>包含附件的郵件</h2>");List<String>users=newArrayList<>();users.add("收件人的郵箱地址");mailSendInfo.setToAddress(users);// 添加附件List<String>files=newArrayList<String>();files.add("C:\\work\\郵件附件.txt");files.add("C:\\work\\名單.xlsx");mailSendInfo.setAttachFileNames(files);MailSender mailSender=newMailSender();mailSender.sendMail(mailSendInfo);}

效果如下:

使用 Spring API 實(shí)現(xiàn)郵件發(fā)送

環(huán)境準(zhǔn)備

創(chuàng)建 Maven 項(xiàng)目,在 pom.xml 文件中添加依賴

<!-- spring核心 jar 依賴 --><dependency><groupId>org.springframework</groupId><artifactId>spring-context</artifactId><version>5.2.4.RELEASE</version></dependency><!--spring 上下文環(huán)境 支持--><dependency><groupId>org.springframework</groupId><artifactId>spring-context-support</artifactId><version>5.2.4.RELEASE</version></dependency><dependency><groupId>org.springframework</groupId><artifactId>spring-test</artifactId><version>5.2.4.RELEASE</version><scope>test</scope></dependency><!-- Java Mail坐標(biāo)依賴 --><dependency><groupId>com.sun.mail</groupId><artifactId>javax.mail</artifactId><version>1.6.2</version></dependency>

配置郵件發(fā)送 bean

在 spring.xml 配置文件中設(shè)置郵件發(fā)送對(duì)應(yīng)的bean標(biāo)簽

<?xml version="1.0" encoding="UTF-8"?><beansxmlns="http://www.springframework.org/schema/beans"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xmlns:context="http://www.springframework.org/schema/context"xsi:schemaLocation="http://www.springframework.org/schema/beans? ? ? http://www.springframework.org/schema/beans/spring-beans.xsd? ? ? http://www.springframework.org/schema/context? ? ? http://www.springframework.org/schema/context/spring-context.xsd"><!-- 開啟自動(dòng)化掃描? --><context:component-scanbase-package="com.xxxx"/><!-- 郵件發(fā)送器(提供了郵件發(fā)送接口彭则、透明創(chuàng)建Java Mail的MimeMessage鳍刷、及郵件發(fā)送的配置) --><beanid="mailSender"class="org.springframework.mail.javamail.JavaMailSenderImpl"><propertyname="host"value="smtp.163.com"/><propertyname="port"value="25"/><propertyname="defaultEncoding"value="utf-8"></property><propertyname="username"value="用戶名"></property><propertyname="password"value="密碼"></property></bean><!-- 普通文本郵件對(duì)象 --><beanid="templateMessage"class="org.springframework.mail.SimpleMailMessage"><propertyname="from"value="發(fā)件人的郵箱地址"/><propertyname="subject"value="spring_mail"/></bean></beans>

定義接口與實(shí)現(xiàn)類

定義接口

packagecom.xxxx.springMail;/**

* 定義接口

*/publicinterfaceOrderManager{voidplaceOrder();}

定義實(shí)現(xiàn)類

packagecom.xxxx.springMail;importorg.springframework.mail.MailException;importorg.springframework.mail.SimpleMailMessage;importorg.springframework.mail.javamail.JavaMailSenderImpl;importorg.springframework.stereotype.Service;importjavax.annotation.Resource;@ServicepublicclassSimpleOrderManagerimplementsOrderManager{@ResourceprivateJavaMailSenderImpl mailSender;@ResourceprivateSimpleMailMessage templateMessage;@OverridepublicvoidplaceOrder(){// 獲取郵件對(duì)象SimpleMailMessage msg=newSimpleMailMessage(this.templateMessage);// 設(shè)置郵件收件人的郵箱地址msg.setTo("收件人的郵箱地址");// 設(shè)置郵件內(nèi)容msg.setText("Hello Spring Mail");try{// 發(fā)送郵件this.mailSender.send(msg);}catch(MailExceptionex){System.err.println(ex.getMessage());}}}

郵件發(fā)送測(cè)試

/**

? *? 發(fā)送郵件

? * @param args

? */publicstaticvoidmain(String[]args){ApplicationContext ac=newClassPathXmlApplicationContext("spring.xml");SimpleOrderManager simpleOrderManager=(SimpleOrderManager)ac.getBean("simpleOrderManager");simpleOrderManager.placeOrder();}

發(fā)送附件

/**

? *? 發(fā)送包含附件的郵件

? * @param args

? * @throws MessagingException

? */publicstaticvoidmain(String[]args)throwsMessagingException{ApplicationContext ac=newClassPathXmlApplicationContext("spring.xml");JavaMailSender mailSender=(JavaMailSender)ac.getBean("mailSender");MimeMessage message=mailSender.createMimeMessage();message.setSubject("spring_mail");// 郵件主題// 創(chuàng)建帶有附件的消息幫組類MimeMessageHelper helper=newMimeMessageHelper(message,true,"utf-8");helper.setTo(newInternetAddress("收件人的郵箱地址"));//設(shè)置接收人helper.setText("Thank you for ordering!");// 郵件內(nèi)容helper.setFrom("發(fā)件人的郵箱地址");// 發(fā)件人// 設(shè)置附件File file=newFile("C:\\work\\郵件附件.txt");// 添加附件helper.addAttachment(file.getName(),file);// 發(fā)送郵件mailSender.send(message);}

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市俯抖,隨后出現(xiàn)的幾起案子输瓜,更是在濱河造成了極大的恐慌,老刑警劉巖蚌成,帶你破解...
    沈念sama閱讀 218,122評(píng)論 6 505
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件前痘,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡担忧,警方通過(guò)查閱死者的電腦和手機(jī)芹缔,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,070評(píng)論 3 395
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)瓶盛,“玉大人最欠,你說(shuō)我怎么就攤上這事示罗。” “怎么了芝硬?”我有些...
    開封第一講書人閱讀 164,491評(píng)論 0 354
  • 文/不壞的土叔 我叫張陵蚜点,是天一觀的道長(zhǎng)。 經(jīng)常有香客問(wèn)我拌阴,道長(zhǎng)绍绘,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,636評(píng)論 1 293
  • 正文 為了忘掉前任迟赃,我火速辦了婚禮陪拘,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘纤壁。我一直安慰自己左刽,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,676評(píng)論 6 392
  • 文/花漫 我一把揭開白布酌媒。 她就那樣靜靜地躺著欠痴,像睡著了一般。 火紅的嫁衣襯著肌膚如雪秒咨。 梳的紋絲不亂的頭發(fā)上喇辽,一...
    開封第一講書人閱讀 51,541評(píng)論 1 305
  • 那天,我揣著相機(jī)與錄音拭荤,去河邊找鬼茵臭。 笑死,一個(gè)胖子當(dāng)著我的面吹牛舅世,可吹牛的內(nèi)容都是我干的旦委。 我是一名探鬼主播,決...
    沈念sama閱讀 40,292評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼雏亚,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼缨硝!你這毒婦竟也來(lái)了?” 一聲冷哼從身側(cè)響起罢低,我...
    開封第一講書人閱讀 39,211評(píng)論 0 276
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤查辩,失蹤者是張志新(化名)和其女友劉穎,沒(méi)想到半個(gè)月后网持,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體宜岛,經(jīng)...
    沈念sama閱讀 45,655評(píng)論 1 314
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,846評(píng)論 3 336
  • 正文 我和宋清朗相戀三年功舀,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了萍倡。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 39,965評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡辟汰,死狀恐怖列敲,靈堂內(nèi)的尸體忽然破棺而出阱佛,到底是詐尸還是另有隱情,我是刑警寧澤戴而,帶...
    沈念sama閱讀 35,684評(píng)論 5 347
  • 正文 年R本政府宣布凑术,位于F島的核電站,受9級(jí)特大地震影響所意,放射性物質(zhì)發(fā)生泄漏淮逊。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,295評(píng)論 3 329
  • 文/蒙蒙 一扁眯、第九天 我趴在偏房一處隱蔽的房頂上張望壮莹。 院中可真熱鬧翅帜,春花似錦姻檀、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,894評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)。三九已至歼疮,卻和暖如春杂抽,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背韩脏。 一陣腳步聲響...
    開封第一講書人閱讀 33,012評(píng)論 1 269
  • 我被黑心中介騙來(lái)泰國(guó)打工缩麸, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人赡矢。 一個(gè)月前我還...
    沈念sama閱讀 48,126評(píng)論 3 370
  • 正文 我出身青樓杭朱,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親吹散。 傳聞我的和親對(duì)象是個(gè)殘疾皇子弧械,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,914評(píng)論 2 355

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

  • Spring 郵件發(fā)送 主要內(nèi)容 JavaMail 概述 ? JavaMail,顧名思義空民,提供給開發(fā)者處理電子...
    java貓貓碎碎閱讀 287評(píng)論 0 0
  • 使用Java應(yīng)用程序發(fā)送 E-mail 十分簡(jiǎn)單刃唐,但需要在設(shè)備上安裝JavaMail API 和Java Acti...
    JWking閱讀 228評(píng)論 0 1
  • Java Mail 簡(jiǎn)介 常見(jiàn)的郵件協(xié)議包括:SMTP(Simple Mail Transfer Protocol...
    Josaber閱讀 3,276評(píng)論 1 9
  • Spring02-模擬用戶登錄,發(fā)送郵件 一.注解方式注入 bean 對(duì)于 bean 的注入,除了使用 xml 配...
    小山居閱讀 692評(píng)論 0 0
  • 久違的晴天界轩,家長(zhǎng)會(huì)画饥。 家長(zhǎng)大會(huì)開好到教室時(shí),離放學(xué)已經(jīng)沒(méi)多少時(shí)間了浊猾。班主任說(shuō)已經(jīng)安排了三個(gè)家長(zhǎng)分享經(jīng)驗(yàn)抖甘。 放學(xué)鈴聲...
    飄雪兒5閱讀 7,523評(píng)論 16 22