Java Mail郵件發(fā)送如何實(shí)現(xiàn)簡單封裝
首先每次發(fā)送需要配置的東西很多,包括發(fā)件人的郵箱和密碼、smtp服務(wù)器和SMTP端口號(hào)等信息。其次,沒有將發(fā)送和郵件內(nèi)容相分離。按照單一職責(zé)原則,應(yīng)該有且僅有一個(gè)原因引起類的變更[1]。最后一個(gè)問題是,我們的代碼不僅自己用,也很可能讓別人調(diào)用。別人調(diào)用的時(shí)候不想去了解郵件發(fā)送的細(xì)節(jié),調(diào)用的人只想傳盡量少的參數(shù)獲得預(yù)期的效果。因此讓Demo變成可以使用的代碼需要我們重新設(shè)計(jì)代碼的結(jié)構(gòu)。
從Demo中我們可以抽象出兩種類型的POJO,也就是發(fā)件人和郵件。你可能會(huì)問收件人怎么辦?收件人可以跟郵件POJO放在一起嗎?
仔細(xì)思考下我們就知道,郵件和收件人應(yīng)該是分開的。因?yàn)槿绻]件和收件人放在一起,那么就意味著我的一封郵件只能發(fā)送給特定的人了,而實(shí)際上我們會(huì)把相同的郵件發(fā)送給不同的收件人。因此收件人只要作為發(fā)送時(shí)的參數(shù)就可以了。
1.發(fā)件人POJO
/** * @Title: MailAuthenticator * @author: ykgao * @description: * @date: 2017-10-11 下午04:55:37 */ import javax.mail.Authenticator; import javax.mail.PasswordAuthentication; /** * 服務(wù)器郵箱登錄驗(yàn)證 * * @author MZULE * */ public class MailAuthenticator extends Authenticator { /** * 用戶名(登錄郵箱) */ private String username; /** * 密碼 */ private String password; /** * 初始化郵箱和密碼 * * @param username 郵箱 * @param password 密碼 */ public MailAuthenticator(String username, String password) { this.username = username; this.password = password; } String getPassword() { return password; } @Override protected PasswordAuthentication getPasswordAuthentication() { return new PasswordAuthentication(username, password); } String getUsername() { return username; } public void setPassword(String password) { this.password = password; } public void setUsername(String username) { this.username = username; } }
2.郵件POJO
用于存儲(chǔ)郵件主題和內(nèi)容。
/** * @Title: SimpleMail * @author: ykgao * @description: * @date: 2017-10-11 下午04:56:27 */ public class SimpleMail { /** 郵件主題 */ public String Subject; /** 郵件內(nèi)容 */ public String Content; /** * @return the subject */ public String getSubject() { return Subject; } /** * @param subject * the subject to set */ public void setSubject(String subject) { Subject = subject; } /** * @return the content */ public String getContent() { return Content; } /** * @param content * the content to set */ public void setContent(String content) { Content = content; } }
3.郵件發(fā)送
設(shè)計(jì)好了POJO,我們現(xiàn)在需要當(dāng)然是發(fā)送郵件了。在Demo中我們需要配置SMTP服務(wù)器,但是我們使用郵箱發(fā)送郵件的時(shí)候并不需要填寫SMTP服務(wù)器。其實(shí)SMTP服務(wù)器大多數(shù)的格式是:smtp.emailType.com。此處emailType 就是你的郵箱類型也就是@后面跟的名稱。比如163郵箱就是163。不過這個(gè)方法也不是萬能的,因?yàn)閛utlook郵箱的smtp服務(wù)器就不是這個(gè)格式,而是smtp-mail.outlook.com ,所以我單獨(dú)為outlook郵箱寫了個(gè)例外。
我們還需要群分郵件的功能。這個(gè)設(shè)計(jì)起來很容易,只需要一個(gè)單人發(fā)送的重載方法,其收件人的參數(shù)可以是一個(gè)List。
為了減少接口的參數(shù)個(gè)數(shù),我們把SMTP端口默認(rèn)為587。
import java.io.UnsupportedEncodingException; import java.security.GeneralSecurityException; import java.util.List; import java.util.Properties; import javaMailDevelopment.SimpleMail; import javax.mail.MessagingException; import javax.mail.Session; import javax.mail.Transport; import javax.mail.internet.AddressException; import javax.mail.internet.InternetAddress; import javax.mail.internet.MimeMessage; import javax.mail.internet.MimeMessage.RecipientType; import com.sun.mail.util.MailSSLSocketFactory; /** * @Title: SimpleMailSender * @author: ykgao * @description: 郵件發(fā)送器 * @date: 2017-10-11 下午04:54:50 */ public class SimpleMailSender { /** * 發(fā)送郵件的props文件 */ private final transient Properties props = System.getProperties(); /** * 郵件服務(wù)器登錄驗(yàn)證 */ private transient MailAuthenticator authenticator; /** * 郵箱session */ private transient Session session; /** * 初始化郵件發(fā)送器 * * @param smtpHostName * SMTP郵件服務(wù)器地址 * @param username * 發(fā)送郵件的用戶名(地址) * @param password * 發(fā)送郵件的密碼 */ public SimpleMailSender(final String smtpHostName, final String username, final String password) { init(username, password, smtpHostName); } /** * 初始化郵件發(fā)送器 * * @param username * 發(fā)送郵件的用戶名(地址),并以此解析SMTP服務(wù)器地址 * @param password * 發(fā)送郵件的密碼 */ public SimpleMailSender(final String username, final String password) { // 通過郵箱地址解析出smtp服務(wù)器,對大多數(shù)郵箱都管用 String smtpHostName = "smtp." + username.split("@")[1]; if (username.split("@")[1].equals("outlook.com")) { smtpHostName = "smtp-mail.outlook.com"; } init(username, password, smtpHostName); } /** * 初始化 * * @param username * 發(fā)送郵件的用戶名(地址) * @param password * 密碼 * @param smtpHostName * SMTP主機(jī)地址 */ private void init(String username, String password, String smtpHostName) { // 初始化props props.setProperty("mail.transport.protocol", "smtp"); // 使用的協(xié)議(JavaMail規(guī)范要求) props.setProperty("mail.smtp.host", smtpHostName); // 發(fā)件人的郵箱的 SMTP 服務(wù)器地址 props.setProperty("mail.smtp.auth", "true"); // 需要請求認(rèn)證 final String smtpPort = "587"; props.setProperty("mail.smtp.port", smtpPort); // props.setProperty("mail.smtp.socketFactory.class", // "javax.net.ssl.SSLSocketFactory"); props.setProperty("mail.smtp.socketFactory.fallback", "false"); props.setProperty("mail.smtp.starttls.enable", "true"); props.setProperty("mail.smtp.socketFactory.port", smtpPort); // 驗(yàn)證 authenticator = new MailAuthenticator(username, password); // 創(chuàng)建session session = Session.getInstance(props, authenticator); session.setDebug(true); } /** * 發(fā)送郵件 * * @param recipient * 收件人郵箱地址 * @param subject * 郵件主題 * @param content * 郵件內(nèi)容 * @throws AddressException * @throws MessagingException * @throws UnsupportedEncodingException */ public void send(String recipient, String subject, Object content) throws Exception { // 創(chuàng)建mime類型郵件 final MimeMessage message = new MimeMessage(session); // 設(shè)置發(fā)信人 message.setFrom(new InternetAddress(authenticator.getUsername())); // 設(shè)置收件人 message.setRecipient(RecipientType.TO, new InternetAddress(recipient)); // 設(shè)置主題 message.setSubject(subject); // 設(shè)置郵件內(nèi)容 message.setContent(content.toString(), "text/html;charset=utf-8"); // 發(fā)送 Transport.send(message); } /** * 群發(fā)郵件 * * @param recipients * 收件人們 * @param subject * 主題 * @param content * 內(nèi)容 * @throws AddressException * @throws MessagingException */ public void send(List<String> recipients, String subject, Object content) throws AddressException, MessagingException { // 創(chuàng)建mime類型郵件 final MimeMessage message = new MimeMessage(session); // 設(shè)置發(fā)信人 message.setFrom(new InternetAddress(authenticator.getUsername())); // 設(shè)置收件人們 final int num = recipients.size(); InternetAddress[] addresses = new InternetAddress[num]; for (int i = 0; i < num; i++) { addresses[i] = new InternetAddress(recipients.get(i)); } message.setRecipients(RecipientType.TO, addresses); // 設(shè)置主題 message.setSubject(subject); // 設(shè)置郵件內(nèi)容 message.setContent(content.toString(), "text/html;charset=utf-8"); // 發(fā)送 Transport.send(message); } /** * 發(fā)送郵件 * * @param recipient * 收件人郵箱地址 @param mail 郵件對象 @throws AddressException @throws * MessagingException @throws */ public void send(String recipient, SimpleMail mail) throws Exception { send(recipient, mail.getSubject(), mail.getContent()); } /** * 群發(fā)郵件 * * @param recipients * 收件人們 * @param mail * 郵件對象 * @throws AddressException * @throws MessagingException */ public void send(List<String> recipients, SimpleMail mail) throws AddressException, MessagingException { send(recipients, mail.getSubject(), mail.getContent()); } }
4.測試代碼
代碼寫完了,現(xiàn)在需要測試下代碼是否可行。
import java.util.ArrayList; import java.util.List; /** * @Title: testMail * @author: ykgao * @description: * @date: 2017-10-11 下午02:13:02 * */ public class testMail { public static void main(String[] args) throws Exception { /** 創(chuàng)建一個(gè)郵件發(fā)送者*/ SimpleMailSender simpleMailSeJava Mail 郵件發(fā)送簡單封裝
以上就是本文的全部內(nèi)容,希望對大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
相關(guān)文章
Spring中@Configuration和@Component注解的區(qū)別及原理
這篇文章主要介紹了Spring中@Configuration和@Component注解的區(qū)別及原理,從功能上來講,這些注解所負(fù)責(zé)的功能的確不相同,但是從本質(zhì)上來講,Spring內(nèi)部都將其作為配置注解進(jìn)行處理,需要的朋友可以參考下2023-11-11Java中ExecutorService和ThreadPoolExecutor運(yùn)行原理
本文主要介紹了Java中ExecutorService和ThreadPoolExecutor運(yùn)行原理,文中通過示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2021-08-08SpringBoot實(shí)現(xiàn)XSS攻擊防御的幾種方式
隨著Web應(yīng)用的普及,網(wǎng)絡(luò)安全問題也日益凸顯,跨站腳本攻擊(Cross-Site Scripting,簡稱XSS)是一種常見的Web安全漏洞,本文旨在探討如何在Spring Boot應(yīng)用程序中有效地防御XSS攻擊,我們將介紹兩種主要的防御手段:注解和過濾器,需要的朋友可以參考下2024-07-07RestTemplate發(fā)送HTTP?GET請求使用方法詳解
這篇文章主要為大家介紹了關(guān)于RestTemplate發(fā)送HTTP?GET請求的使用方法詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家<BR>33+多多進(jìn)步2022-03-03Spring?Lifecycle?和?SmartLifecycle區(qū)別面試精講
這篇文章主要為大家介紹了Spring?Lifecycle和SmartLifecycle的區(qū)別面試精講,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2023-10-10Java實(shí)現(xiàn)對象按照其屬性排序的兩種方法示例
這篇文章主要介紹了Java實(shí)現(xiàn)對象按照其屬性排序的兩種方法,結(jié)合實(shí)例形式詳細(xì)分析了Java對象按照其屬性排序的兩種實(shí)現(xiàn)方法與相關(guān)注意事項(xiàng),需要的朋友可以參考下2020-05-05gradle配置國內(nèi)鏡像的實(shí)現(xiàn)
這篇文章主要介紹了gradle配置國內(nèi)鏡像的實(shí)現(xiàn),文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2020-07-07