SpringBoot2.0高階案例(03):整合 JavaMail ,實現非同步傳送郵件
本文原始碼
碼雲地址:知了一笑
https://gitee.com/cicadasmile/middle-ware-parent
一、JavaMail的核心API
1、API功能圖解
2、API說明
(1)、Message 類: javax.mail.Message 類是建立和解析郵件的一個抽象類 子類javax.mail.internet.MimeMessage :表示一份電子郵件。 傳送郵件時,首先創建出封裝了郵件資料的 Message 物件, 然後把這個物件傳遞給郵件傳送Transport 類,執行傳送。 接收郵件時,把接收到的郵件資料封裝在Message 類的例項中,從這個物件中解析收到的郵件資料。
(2)、Transport 類 javax.mail.Transport 類是傳送郵件的核心API 類 建立好 Message 物件後, 只需要使用郵件傳送API 得到 Transport 物件, 然後把 Message 物件傳遞給 Transport 物件, 並呼叫它的傳送方法, 就可以把郵件傳送給指定的郵件伺服器。
(3)、Store 類 javax.mail.Store 類是接收郵件的核心 API 類 例項物件代表實現了某個郵件接收協議的郵件接收物件,接收郵件時, 只需要得到 Store 物件, 然後呼叫 Store 物件的接收方法,就可以從指定的郵件伺服器獲得郵件資料,並把這些郵件資料封裝到表示郵件的 Message 物件中。
(4)、Session 類: javax.mail.Session 類定義郵件伺服器的主機名、埠號、協議等 Session 物件根據這些資訊構建用於郵件收發的 Transport 和 Store 物件, 以及為客戶端建立 Message 物件時提供資訊支援。
二、郵件伺服器配置
以 smtp 為例
1、smtp.mxhichina.com
阿里雲企業郵箱配置(賬號+密碼)
2、smtp.aliyun.com
阿里雲個人郵箱配置(賬號+密碼)
3、smtp.163.com
網易郵箱配置(賬號+授權碼)
三、公共程式碼塊
1、郵件通用配置
package com.email.send.param; /** * 郵箱傳送引數配置 */ public class EmailParam { /** * 郵箱伺服器地址 */ // public static final String emailHost = "smtp.mxhichina.com" ; 阿里雲企業郵箱配置(賬號+密碼) // public static final String emailHost = "smtp.aliyun.com" ; 阿里雲個人郵箱配置(賬號+密碼) public static final String emailHost = "smtp.163.com" ; // 網易郵箱配置(賬號+授權碼) /** * 郵箱協議 */ public static final String emailProtocol = "smtp" ; /** * 郵箱發件人 */ public static final String emailSender = "[email protected]" ; /** * 郵箱授權碼 */ public static final String password = "authCode"; /** * 郵箱授權 */ public static final String emailAuth = "true" ; /** * 郵箱暱稱 */ public static final String emailNick = "知了一笑" ; }
2、常用常量
package com.email.send.param;
/**
* 郵件傳送型別
*/
public enum EmailType {
EMAIL_TEXT_KEY("email_text_key", "文字郵件"),
EMAIL_IMAGE_KEY("email_image_key", "圖片郵件"),
EMAIL_FILE_KEY("email_file_key", "檔案郵件");
private String code;
private String value;
EmailType(String code, String value) {
this.code = code;
this.value = value;
}
public static String getByCode(String code) {
EmailType[] values = EmailType.values();
for (EmailType emailType: values) {
if (emailType.code.equalsIgnoreCase(code)) {
return emailType.value;
}
}
return null;
}
// 省略 get set
}
四、郵件傳送封裝
1、純文字郵件傳送
(1)、程式碼封裝
/**
* 郵箱傳送模式01:純文字格式
*/
public static void sendEmail01(String receiver, String title, String body) throws Exception {
Properties prop = new Properties();
prop.setProperty("mail.host", EmailParam.emailHost);
prop.setProperty("mail.transport.protocol", EmailParam.emailProtocol);
prop.setProperty("mail.smtp.auth", EmailParam.emailAuth);
//使用JavaMail傳送郵件的5個步驟
//1、建立session
Session session = Session.getInstance(prop);
//開啟Session的debug模式,這樣就可以檢視到程式傳送Email的執行狀態
session.setDebug(true);
//2、通過session得到transport物件
Transport ts = session.getTransport();
//3、使用郵箱的使用者名稱和密碼連上郵件伺服器,傳送郵件時,發件人需要提交郵箱的使用者名稱和密碼給smtp伺服器,使用者名稱和密碼都通過驗證之後才能夠正常傳送郵件給收件人。
ts.connect(EmailParam.emailHost, EmailParam.emailSender, EmailParam.password);
//4、建立郵件
// Message message = createEmail01(session,receiver,title,body);
Message message = createEmail01(session, receiver, title, body);
//5、傳送郵件
ts.sendMessage(message, message.getAllRecipients());
ts.close();
}
/**
* 建立文字郵件
*/
private static MimeMessage createEmail01(Session session, String receiver, String title, String body)
throws Exception {
//建立郵件物件
MimeMessage message = new MimeMessage(session);
//指明郵件的發件人
String nick = javax.mail.internet.MimeUtility.encodeText(EmailParam.emailNick);
message.setFrom(new InternetAddress(nick + "<" + EmailParam.emailSender + ">"));
//指明郵件的收件人
message.setRecipient(Message.RecipientType.TO, new InternetAddress(receiver));
//郵件的標題
message.setSubject(title);
//郵件的文字內容
message.setContent(body, "text/html;charset=UTF-8");
//返回建立好的郵件物件
return message;
}
(2)、執行效果圖
2、文字+圖片+附件郵件
(1)、程式碼封裝
/**
* 郵箱傳送模式02:複雜格式
*/
public static void sendEmail02(String receiver, String title, String body) throws Exception {
Properties prop = new Properties();
prop.setProperty("mail.host", EmailParam.emailHost);
prop.setProperty("mail.transport.protocol", EmailParam.emailProtocol);
prop.setProperty("mail.smtp.auth", EmailParam.emailAuth);
//使用JavaMail傳送郵件的5個步驟
//1、建立session
Session session = Session.getInstance(prop);
//開啟Session的debug模式,這樣就可以檢視到程式傳送Email的執行狀態
session.setDebug(true);
//2、通過session得到transport物件
Transport ts = session.getTransport();
//3、使用郵箱的使用者名稱和密碼連上郵件伺服器,傳送郵件時,發件人需要提交郵箱的使用者名稱和密碼給smtp伺服器,使用者名稱和密碼都通過驗證之後才能夠正常傳送郵件給收件人。
ts.connect(EmailParam.emailHost, EmailParam.emailSender, EmailParam.password);
//4、建立郵件
// Message message = createEmail01(session,receiver,title,body);
Message message = createEmail02(session, receiver, title, body);
//5、傳送郵件
ts.sendMessage(message, message.getAllRecipients());
ts.close();
}
private static MimeMessage createEmail02(Session session, String receiver, String title, String body)
throws Exception {
//建立郵件物件
MimeMessage message = new MimeMessage(session);
//指明郵件的發件人
String nick = javax.mail.internet.MimeUtility.encodeText(EmailParam.emailNick);
message.setFrom(new InternetAddress(nick + "<" + EmailParam.emailSender + ">"));
//指明郵件的收件人
message.setRecipient(Message.RecipientType.TO, new InternetAddress(receiver));
//郵件的標題
message.setSubject(title);
//文字內容
MimeBodyPart text = new MimeBodyPart();
text.setContent(body, "text/html;charset=UTF-8");
//圖片內容
MimeBodyPart image = new MimeBodyPart();
image.setDataHandler(new DataHandler(new FileDataSource("ware-email-send/src/gzh.jpg")));
image.setContentID("gzh.jpg");
//附件內容
MimeBodyPart attach = new MimeBodyPart();
DataHandler file = new DataHandler(new FileDataSource("ware-email-send/src/gzh.zip"));
attach.setDataHandler(file);
attach.setFileName(file.getName());
//關係:正文和圖片
MimeMultipart multipart1 = new MimeMultipart();
multipart1.addBodyPart(text);
multipart1.addBodyPart(image);
multipart1.setSubType("related");
//關係:正文和附件
MimeMultipart multipart2 = new MimeMultipart();
multipart2.addBodyPart(attach);
// 全文內容
MimeBodyPart content = new MimeBodyPart();
content.setContent(multipart1);
multipart2.addBodyPart(content);
multipart2.setSubType("mixed");
// 封裝 MimeMessage 物件
message.setContent(multipart2);
message.saveChanges();
// 本地檢視檔案格式
message.writeTo(new FileOutputStream("F:\\MixedMail.eml"));
//返回建立好的郵件物件
return message;
}
(2)、執行效果
3、實現非同步傳送
(1)、配置非同步執行執行緒
package com.email.send.util;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
import java.util.concurrent.Executor;
import java.util.concurrent.ThreadPoolExecutor;
/**
* 定義非同步任務執行執行緒池
*/
@Configuration
public class TaskPoolConfig {
@Bean("taskExecutor")
public Executor taskExecutor () {
ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
// 核心執行緒數10:執行緒池建立時候初始化的執行緒數
executor.setCorePoolSize(10);
// 最大執行緒數20:執行緒池最大的執行緒數,只有在緩衝佇列滿了之後才會申請超過核心執行緒數的執行緒
executor.setMaxPoolSize(15);
// 緩衝佇列200:用來緩衝執行任務的佇列
executor.setQueueCapacity(200);
// 允許執行緒的空閒時間60秒:當超過了核心執行緒數之外的執行緒在空閒時間到達之後會被銷燬
executor.setKeepAliveSeconds(60);
// 執行緒池名的字首:設定好了之後可以方便定位處理任務所在的執行緒池
executor.setThreadNamePrefix("taskExecutor-");
/*
執行緒池對拒絕任務的處理策略:這裡採用了CallerRunsPolicy策略,
當執行緒池沒有處理能力的時候,該策略會直接在 execute 方法的呼叫執行緒中執行被拒絕的任務;
如果執行程式已關閉,則會丟棄該任務
*/
executor.setRejectedExecutionHandler(new ThreadPoolExecutor.CallerRunsPolicy());
// 設定執行緒池關閉的時候等待所有任務都完成再繼續銷燬其他的Bean
executor.setWaitForTasksToCompleteOnShutdown(true);
// 設定執行緒池中任務的等待時間,如果超過這個時候還沒有銷燬就強制銷燬,以確保應用最後能夠被關閉,而不是阻塞住。
executor.setAwaitTerminationSeconds(600);
return executor;
}
}
(2)、業務方法使用
注意兩個註解 @Component @Async("taskExecutor")
@Component
@Service
public class EmailServiceImpl implements EmailService {
@Async("taskExecutor")
@Override
public void sendEmail(String emailKey, SendEmailModel model) {
try{
// 非同步執行
Thread.sleep(1000);
String textBody = EmailUtil.convertTextModel(BodyType.getByCode(emailKey),"知了","一笑");
// 傳送文字郵件
EmailUtil.sendEmail01(model.getReceiver(), EmailType.getByCode(emailKey),textBody);
// 傳送複雜郵件:文字+圖片+附件
String body = "自定義圖片:<img src="cid:gzh.jpg">,網路圖片:<img src="https://oscimg.oschina.net/oscnet/8800276_184927469000_2.png">";
// EmailUtil.sendEmail02(model.getReceiver(),"文字+圖片+附件",body);
} catch (Exception e){
e.printStackTrace();
}
}
}
(3)、啟動類註解
@EnableAsync
@EnableAsync
@SpringBootApplication
public class EmailApplication {
public static void main(String[] args) {
SpringApplication.run(EmailApplication.class,args) ;
}
}
五、原始碼地址
GitHub地址:知了一笑
https://github.com/cicadasmile/middle-ware-parent
碼雲地址:知了一笑
https://gitee.com/cicadasmile/middle-ware-parent
相關推薦
SpringBoot2.0高階案例(03):整合 JavaMail ,實現非同步傳送郵件
本文原始碼 碼雲地址:知了一笑 https://gitee.com/cicadasmile/middle-ware-parent
SpringBoot2.0高階案例(02) :整合 RocketMQ ,實現請求非同步處理
本文原始碼 碼雲地址:知了一笑 https://gitee.com/cicadasmile/middle-ware-parent
SpringBoot2.0高階案例(06):整合 QuartJob ,實現定時器實時管理
一、QuartJob簡介 1、一句話描述 Quartz是一個完全由java編寫的開源作業排程框架,形式簡易,功能強大。 2、核心A
SpringBoot2.0高階案例(05):整合 Swagger2 ,構建介面管理介面
一、Swagger2簡介 1、Swagger2優點 整合到Spring Boot中,構建強大RESTful API文件。省去介面文
SpringBoot2.0高階案例(09):整合 ElasticSearch框架,實現高效能搜尋引擎
本文原始碼 碼雲地址:知了一笑 https://gitee.com/cicadasmile/middle-ware-parent
SpringBoot2.0高階案例(12):整合 SpringSecurity 框架,實現使用者許可權安全管理
一、Security簡介 1、基礎概念 Spring Security是一個能夠為基於Spring的企業應用系統提供宣告式的安全訪
SpringBoot2.0高階案例(10):整合 JWT 框架,解決Token跨域驗證問題
GitHub原始碼地址:知了一笑 https://github.com/cicadasmile/middle-ware-paren
SpringBoot2.0高階案例(08):整合 Dubbo框架 ,實現RPC服務遠端呼叫
一、Dubbo框架簡介 1、框架依賴 圖例說明: 1)圖中小方塊 Protocol, Cluster, Proxy, Servi
SpringBoot2.0高階案例(07) 整合:Redis叢集 ,實現訊息佇列場景
本文原始碼 GitHub地址:知了一笑 https://github.com/cicadasmile/middle-ware-pa
SpringBoot2高階案例(11):整合 FastDFS 中介軟體,實現檔案分散式管理
一、FastDFS簡介 1、FastDFS作用 FastDFS是一個開源的輕量級分散式檔案系統,它對檔案進行管理,功能包括:檔案儲
SpringBoot--01.SpringBoot2.0入門案例
一、SpringBoot簡介 1、SpringBoot概述(簡化配置、開箱即用) - 為所有 Spring 的開發者提供一個非常快速的、廣泛接受的入門體驗 - 開箱即用(啟動器starter-其實就是SpringBoot提供的一個jar包),但通過自己設定參 (.properties),
微服務 SpringBoot 2.0(九):整合Mybatis
我是SQL小白,我選Mybatis —— Java面試必修 引言 在第五章我們已經整合了Thymeleaf頁面框架,第七章也整合了JdbcTemplate,那今天我們再結合資料庫整合Mybatis框架 在接下來的文章中,我會用一個開源的部落格原始碼來做講解
Springboot2.0啟動報錯:java.lang.NoClassDefFoundError: ch/qos/logback/core/spi/LifeCycle
springboot2.0啟動報錯: java.lang.NoClassDefFoundError: ch/qos/logback/core/spi/LifeCycle at java.lang.ClassLoader.defineClass1(Native Met
springBoot2.0 MyBatis Redis 及RedisCache 整合附demo
springboot2.0 + mybatis 或者 springboot2.0 + redis 在網上可以找到很多資料,但是大都不全或者有這樣那樣的問題,所以便自己動手寫了個demo,能只用 yaml 配置的,儘量不再寫程式碼。 pom.xml <?xml ver
springboot學習入門簡易版四---springboot2.0靜態資源訪問及整合freemarker視圖層
nbsp 規則 pri stat path 整合 位置 啟動程序 -- 2.4.4 SpringBoot靜態資源訪問(9) Springboot默認提供靜態資源目錄位置需放在classpath下,目錄名需要符合如下規則 /static /public /resour
微服務架構案例(03):資料庫選型簡介,業務資料規劃設計
更新進度(共6節): 01:專案技術選型簡介,架構圖解說明 02:業務架構設計,系統分層管理 03:資料庫選型,業務資料設計規劃 一、資料庫選擇 1、資料庫分類 資料庫型別 常見資料庫 關係型 MySQL、Oracle、DB2、SQLServer等。 非關係型 Hbase、Red
精通SpringBoot——第七篇:整合Redis實現快取
專案中用到快取是很常見的事情, 快取能夠提升系統訪問的速度,減輕對資料庫的壓力等好處。今天我們來講講怎麼在spring boot 中整合redis 實現對資料庫查詢結果的快取。 首先第一步要做的就是在pom.xml檔案新增spring-boot-starter-data-redis。 要整合快取,必
ionic學習(七):問答社群03:登入功能實現 總結篇
登入功能整整搞了一天,期間各種錯誤不斷,剛接觸ionic,對Angular也不太熟悉,沒正規的學過html,css,js等前端知識。 整理一下流程: 1.製作登入頁面 2.構造登入等待遮罩層和登入錯誤遮罩層 3.通過storge儲存登入的資訊 4.通過判斷是否登入,並顯示相應頁面 備
Spring Cloud 安全:整合OAuth2實現身份認證和單點登入
1、概述 Spring Cloud 的安全模組可以為Spring Boot應用提供基於令牌的安全特性。具體講就是支援OAuth2協議來實現單點登入(SSO),可以很方便地在資源服務之間傳遞身份令牌,以及使用嵌入式的ZUUL代理來配置下游服務的認證。 在這篇文
最課程階段大作業03:用半天實現淘寶首頁?
每一個在最課程學習的學生,到了最後幾乎都會來問我一個問題:老師,是不是實際的開發中,都會有一個前端開發工程師,把靜態頁面做好了,然後才交給我們後臺開發啊? 我只能說:你想多了。 我知道你這麼問的意思,HTML+CSS+各類前端框架學習起來太繁瑣了,是不是就沒有