本文簡要介紹如何通過Spring框架的支持,通過QQ郵箱來發送郵件,包括簡單文本,附件、以及內聯圖片、HTML以及HTTP圖片。
spring-context-support很早就內置支持郵件發送。
當然, 官方文檔明確指出, 需要依賴 JavaMail 這個庫。
在這個年代, 我們很少自己搭建 smtp 服務器來發送郵件, 一般都是使用郵件提供商的服務。 例如 QQ郵箱, 企業郵箱, 163, 或者阿里雲之類的廠商。
註冊一個賬號, 然後參考郵件服務商的幫助中心, 以及賬戶設置頁面, 獲取smtp服務器端口信息, 以及你註冊的賬號和密碼, 保存到一個比較安全的地方。
相關依賴。
pom.xml中的依賴如下:
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context-support</artifactId>
<version>4.0.7.RELEASE</version>
</dependency>
<dependency>
<groupId>javax.mail</groupId>
<artifactId>mail</artifactId>
<version>1.4.7</version>
</dependency>
<dependency>
<groupId>commons-io</groupId>
<artifactId>commons-io</artifactId>
<version>2.2</version>
</dependency>
其中, commons-io
根據需要決定, 本文中使用了 IOUtils工具類, 提供了很多方便又強大的IO工具方法, 有興趣可以研究一下。
Spring-Mail 相關的接口與實現類
MailSender
, 發送簡單郵件的頂層接口。JavaMailSender
, 繼承頂層接口, 支持發送 MIME 郵件。JavaMailSenderImpl
實現類, 顧名思義。SimpleMailMessage
類, 簡單郵件信息, 包括from
,to
,cc
,subject
以及text
字段。MimeMessagePreparator
接口, 用於 MIME 郵件回調。MimeMessageHelper
輔助類, 可用於創建 MIME 郵件。支持圖片、附件、以及 HTML 樣式等。
簡單測試代碼
下面是簡單的測試代碼。 實際使用時請參考本文末尾的相關鏈接。把代碼組織好看一點,好用一點。
package com.cncounter.test.spring;
import org.springframework.mail.MailException;
import org.springframework.mail.SimpleMailMessage;
import org.springframework.mail.javamail.JavaMailSenderImpl;
public class TestSpringEmail {
public static void main(String[] args) {
//
sendTextEmail();
}
public static void sendTextEmail() {
//
JavaMailSenderImpl mailSender = new JavaMailSenderImpl();
// 參考QQ郵箱幫助中心
mailSender.setHost("smtp.qq.com"); // QQ郵箱smtp發送服務器地址
//mailSender.setPort(465); // QQ這個端口不可用
mailSender.setPort(587);// 端口號
mailSender.setUsername("[email protected]"); // 使用你自己的賬號
mailSender.setPassword("usbusbcnzztbsbtob"); // 授權碼-發短信獲取
// 郵件信息
SimpleMailMessage msg = new SimpleMailMessage();
msg.setFrom("[email protected]"); // 發件人郵箱
msg.setTo("[email protected]"); // 收件人郵箱
msg.setSubject("測試Spring郵件"); // 標題
msg.setText("您的訂單號碼: 20181120075; 請勿告訴別人!"); // 文本信息
try {
mailSender.send(msg);
System.out.println("郵件發送成功!"); // 沒有報錯就是好消息 :-)
} catch (MailException ex) {
System.err.println("發送失敗:" + ex.getMessage());
}
}
}
測試結果如下圖所示:
可以看到, 簡單驗證碼之類的文本, 通過這些封裝好的工具類, 代碼編寫很容易。
發送附件示例
以下是發送附件的示例。 根據需要, 可以發送多個附件。
package com.cncounter.test.spring;
import org.apache.commons.io.IOUtils;
import org.springframework.core.io.ByteArrayResource;
import org.springframework.mail.MailException;
import org.springframework.mail.javamail.*;
import javax.mail.MessagingException;
import javax.mail.internet.MimeMessage;
import java.io.*;
import java.util.Properties;
public class TestSpringAttachEmail {
public static void main(String[] args) throws Exception {
// 發送帶附件的MIME郵件
sendAttachmentEmail();
}
// 發送帶附件的MIME郵件
public static void sendAttachmentEmail() throws MessagingException, IOException {
// 郵件發送器
JavaMailSender mailSender = getJavaMailSender();
// MIME 郵件
MimeMessage mimeMessage = mailSender.createMimeMessage();
// 輔助類; 明確使用 UTF-8 編碼; 否則HTML報中文亂碼
MimeMessageHelper helper = new MimeMessageHelper(mimeMessage, true, "UTF-8");
//
boolean isHTML = true;
// 郵件信息
helper.setFrom("[email protected]"); // 發件人郵箱
helper.setTo("[email protected]"); // 收件人郵箱
helper.setSubject("測試Spring發送附件-1"); // 標題
helper.setText("請點擊: <a href='http://www.yuledanao.com/dl/PWA_INTRO.zip'><b>PWA開發簡介.zip</b></a>;" +
" 或者下載附件!", isHTML); // HTML-信息
// 增加1個附件; 可以使用多種資源API
String fileName1 = "E:/PWA開發簡介.zip";
InputStream inputStream1 = new FileInputStream(fileName1);
//
// Java Mail 會打開2次 InputStreamResource
// 第一次確定編碼, 第二次才執行編碼。
ByteArrayResource byteResource1 =
new ByteArrayResource(IOUtils.toByteArray(inputStream1));
// 所以不能使用 InputStreamResource
// InputStreamResource attachment1 = new InputStreamResource(inputStream1);
helper.addAttachment("PWA開發簡介.zip", byteResource1);
try {
mailSender.send(mimeMessage);
System.out.println("郵件發送成功!"); // 沒有報錯就是好消息 :-)
} catch (MailException ex) {
System.err.println("發送失敗:" + ex.getMessage());
} finally {
IOUtils.closeQuietly(inputStream1);
}
}
// 獲取郵件發送器
public static JavaMailSender getJavaMailSender() {
//
JavaMailSenderImpl mailSender = new JavaMailSenderImpl();
// 參考QQ郵箱幫助中心
mailSender.setHost("smtp.qq.com"); // QQ郵箱smtp發送服務器地址
//mailSender.setPort(465); // QQ這個端口不可用? 爲什麼?
mailSender.setPort(587);// 端口號
mailSender.setUsername("[email protected]"); // 使用你自己的賬號
mailSender.setPassword("usbusbcnzztbsbtob"); // 授權碼-發短信獲取
//
// 相關屬性配置, 也可以不修改,使用默認值
Properties props = mailSender.getJavaMailProperties();
props.put("mail.transport.protocol", "smtp");// 協議
props.put("mail.smtp.auth", "true");// 登錄
props.put("mail.smtp.starttls.enable", "true");//使用SSL
props.put("mail.debug", "true");// 調試信息輸出
//
return mailSender;
}
}
當然, 具體的代碼請根據需要進行適當的封裝。 比如自定義工具類。
結果如下圖所示:
發送內聯圖片示例
有兩種手段,請根據需要選擇:
- HTML嵌入http路徑的圖片。
- 以內聯資源的方式發送圖片。
以下是這兩種內聯圖片的示例:
package com.cncounter.test.spring;
import org.apache.commons.io.IOUtils;
import org.springframework.core.io.ByteArrayResource;
import org.springframework.mail.MailException;
import org.springframework.mail.javamail.JavaMailSender;
import org.springframework.mail.javamail.JavaMailSenderImpl;
import org.springframework.mail.javamail.MimeMessageHelper;
import javax.mail.MessagingException;
import javax.mail.internet.MimeMessage;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.Properties;
public class TestSpringImageEmail {
public static void main(String[] args) throws Exception {
// 發送帶內聯圖片的MIME郵件
sendImageEmail();
}
// 發送帶內聯圖片的MIME郵件
public static void sendImageEmail() throws MessagingException, IOException {
// 郵件發送器
JavaMailSender mailSender = getJavaMailSender();
// MIME 郵件
MimeMessage mimeMessage = mailSender.createMimeMessage();
// 輔助類; 明確使用 UTF-8 編碼; 否則HTML報中文亂碼
MimeMessageHelper helper = new MimeMessageHelper(mimeMessage, true, "UTF-8");
//
boolean isHTML = true;
// 郵件信息
helper.setFrom("[email protected]"); // 發件人郵箱
helper.setTo("[email protected]"); // 收件人郵箱
helper.setSubject("測試Spring發送內聯圖片-3"); // 標題
helper.setText("<h1>測試圖片</h1>" +
"海信電視-InLine:" +
"<br/>" +
"<a target='_blank' href='http://www.yuledanao.com/dl/haixin.png'><img src='cid:image1' /></a>" +
"<br/>" +
"img-src-http資源:" +
"<br/>" +
"<a target='_blank' href='http://www.yuledanao.com/dl/haixin.png'><img src='http://www.yuledanao.com/dl/haixin.png' /></a>" +
"<br/>" +
"<br/>" +
"請點擊: <a target='_blank' href='http://www.yuledanao.com/dl/PWA_INTRO.zip'><b>PWA開發簡介.zip</b></a>;" +
" 或者下載附件!", isHTML); // HTML-信息
// cid - content-ID
// 增加內聯圖片:
// 不作爲附件發送
String imageName1 = "E:/haixin.png";
InputStream imageInputStream1 = new FileInputStream(imageName1);
ByteArrayResource imageResource1 =
new ByteArrayResource(IOUtils.toByteArray(imageInputStream1));
helper.addInline("image1", imageResource1, "image/png");
// 增加1個附件; 可以使用多種資源API
String fileName1 = "E:/PWA開發簡介.zip";
InputStream inputStream1 = new FileInputStream(fileName1);
//
// Java Mail 會打開2次 InputStreamResource;
// 第一次確定編碼, 第二次才執行編碼。
ByteArrayResource byteResource1 =
new ByteArrayResource(IOUtils.toByteArray(inputStream1));
// 所以不能直接使用 InputStreamResource
// InputStreamResource attachment1 = new InputStreamResource(inputStream1);
helper.addAttachment("PWA開發簡介.zip", byteResource1);
try {
mailSender.send(mimeMessage);
System.out.println("郵件發送成功!"); // 沒有報錯就是好消息 :-)
} catch (MailException ex) {
System.err.println("發送失敗:" + ex.getMessage());
} finally {
IOUtils.closeQuietly(inputStream1);
}
}
// 獲取郵件發送器
public static JavaMailSender getJavaMailSender() {
//
JavaMailSenderImpl mailSender = new JavaMailSenderImpl();
// 參考QQ郵箱幫助中心
mailSender.setHost("smtp.qq.com"); // QQ郵箱smtp發送服務器地址
//mailSender.setPort(465); // QQ這個端口不可用? 爲什麼?
mailSender.setPort(587);// 端口號
mailSender.setUsername("[email protected]"); // 使用你自己的賬號
mailSender.setPassword("usbusbcnzztbsbtob"); // 授權碼-發短信獲取
//
// 相關屬性配置, 也可以不修改,使用默認值
Properties props = mailSender.getJavaMailProperties();
props.put("mail.transport.protocol", "smtp");// 協議
props.put("mail.smtp.auth", "true");// 登錄
props.put("mail.smtp.starttls.enable", "true");//使用SSL
//props.put("mail.debug", "true");// 調試信息輸出
//
return mailSender;
}
}
如果在公網上沒有固定的HTTP服務器或者CDN服務器, 則需要使用內聯的方式來發送圖片。
可以從網絡上下載到圖片資源, 則引用 HTTP 資源更簡單便捷。
需要CSS樣式則設置HTML元素的style屬性即可。
執行結果如下圖所示:
和發送附件並不衝突。如果需要發送很多圖片, 可以使用模板技術, 以及 Map/Bean來封裝傳入的數據。
更多信息, 請參考相關鏈接。
相關鏈接
Spring Email使用教程: http://www.baeldung.com/spring-email
spring集成Email文檔: https://docs.spring.io/spring/docs/current/spring-framework-reference/integration.html#mail
日期: 2018年4月8日