Java Mail郵件發(fā)送如何實(shí)現(xiàn)簡(jiǎn)單封裝
首先每次發(fā)送需要配置的東西很多,包括發(fā)件人的郵箱和密碼、smtp服務(wù)器和SMTP端口號(hào)等信息。其次,沒(méi)有將發(fā)送和郵件內(nèi)容相分離。按照單一職責(zé)原則,應(yīng)該有且僅有一個(gè)原因引起類的變更[1]。最后一個(gè)問(wèn)題是,我們的代碼不僅自己用,也很可能讓別人調(diào)用。別人調(diào)用的時(shí)候不想去了解郵件發(fā)送的細(xì)節(jié),調(diào)用的人只想傳盡量少的參數(shù)獲得預(yù)期的效果。因此讓Demo變成可以使用的代碼需要我們重新設(shè)計(jì)代碼的結(jié)構(gòu)。
從Demo中我們可以抽象出兩種類型的POJO,也就是發(fā)件人和郵件。你可能會(huì)問(wèn)收件人怎么辦?收件人可以跟郵件POJO放在一起嗎?
仔細(xì)思考下我們就知道,郵件和收件人應(yīng)該是分開(kāi)的。因?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í)候并不需要填寫(xiě)SMTP服務(wù)器。其實(shí)SMTP服務(wù)器大多數(shù)的格式是:smtp.emailType.com。此處emailType 就是你的郵箱類型也就是@后面跟的名稱。比如163郵箱就是163。不過(guò)這個(gè)方法也不是萬(wàn)能的,因?yàn)閛utlook郵箱的smtp服務(wù)器就不是這個(gè)格式,而是smtp-mail.outlook.com ,所以我單獨(dú)為outlook郵箱寫(xiě)了個(gè)例外。
我們還需要群分郵件的功能。這個(gè)設(shè)計(jì)起來(lái)很容易,只需要一個(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) {
// 通過(guò)郵箱地址解析出smtp服務(wù)器,對(duì)大多數(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"); // 需要請(qǐng)求認(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 郵件對(duì)象 @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
* 郵件對(duì)象
* @throws AddressException
* @throws MessagingException
*/
public void send(List<String> recipients, SimpleMail mail) throws AddressException, MessagingException {
send(recipients, mail.getSubject(), mail.getContent());
}
}
4.測(cè)試代碼
代碼寫(xiě)完了,現(xiàn)在需要測(cè)試下代碼是否可行。
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ā)送簡(jiǎn)單封裝
以上就是本文的全部?jī)?nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
相關(guān)文章
httpclient ConnectionHolder連接池連接保持源碼解析
這篇文章主要為大家介紹了httpclient ConnectionHolder連接池連接保持源碼解析,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2023-11-11
Spring循環(huán)依賴正確性及Bean注入的順序關(guān)系詳解
這篇文章主要給大家介紹了關(guān)于Spring循環(huán)依賴的正確性,以及Bean注入的順序關(guān)系的相關(guān)資料,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧。2018-01-01
Java8新特性之類型注解_動(dòng)力節(jié)點(diǎn)Java學(xué)院整理
這篇文章主要介紹了Java8新特性之類型注解的相關(guān)資料,需要的朋友可以參考下2017-06-06
Java 入門(mén)圖形用戶界面設(shè)計(jì)之單選按鈕
圖形界面(簡(jiǎn)稱GUI)是指采用圖形方式顯示的計(jì)算機(jī)操作用戶界面。與早期計(jì)算機(jī)使用的命令行界面相比,圖形界面對(duì)于用戶來(lái)說(shuō)在視覺(jué)上更易于接受,本篇精講Java語(yǔ)言中關(guān)于圖形用戶界面的單選按鈕2022-02-02
Java語(yǔ)言實(shí)現(xiàn)簡(jiǎn)單FTP軟件 FTP上傳下載管理模塊實(shí)現(xiàn)(11)
這篇文章主要為大家詳細(xì)介紹了Java語(yǔ)言實(shí)現(xiàn)簡(jiǎn)單FTP軟件,F(xiàn)TP本地文件管理模塊的實(shí)現(xiàn)方法,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2017-04-04
Java Socket實(shí)現(xiàn)的傳輸對(duì)象功能示例
這篇文章主要介紹了Java Socket實(shí)現(xiàn)的傳輸對(duì)象功能,結(jié)合具體實(shí)例形式分析了java socket傳輸對(duì)象的原理及接口、客戶端、服務(wù)器端相關(guān)實(shí)現(xiàn)技巧,需要的朋友可以參考下2017-06-06
Java中關(guān)于size()>0?和isEmpt()的性能考量
這篇文章主要介紹了Java中關(guān)于size()>0?和isEmpt()性能考量,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2022-02-02

