1.啊掏、電子郵件協(xié)議
電子郵件的在網(wǎng)絡(luò)中傳輸和網(wǎng)頁一樣需要遵從特定的協(xié)議,常用的電子郵件協(xié)議包括 SMTP衰猛,POP3迟蜜,IMAP。其中郵件的創(chuàng)建和發(fā)送只需要用到 SMTP協(xié)議啡省,所以本文也只會涉及到SMTP協(xié)議娜睛。SMTP 是 Simple Mail Transfer Protocol 的簡稱,即簡單郵件傳輸協(xié)議卦睹。
2畦戒、JavaMail
JavaMail 下載地址: https://github.com/javaee/javamail/releases
3、在項目中的具體應(yīng)用
3.1在項目的resources下新建一個jmail.properties文件
#發(fā)件人的郵箱
jmail.myEmailAccount=XXX@163.com
#發(fā)件人的郵箱密碼
jmail.myEmailPassword=XXX
#發(fā)件人郵箱的 SMTP 服務(wù)器地址
jmail.myEmailSMTPHost=smtp.163.com
#收件人郵箱
jmail.receiveMailAccount=XXX@163.com
#使用的協(xié)議名
jmail.protocolName=mail.transport.protocol
#使用的協(xié)議值
jmail.protocolValue=smtp
#發(fā)件人的郵箱的 SMTP 服務(wù)器地址名稱
jmail.hostName=mail.smtp.host
#請求認證名稱
jmail.authName=mail.smtp.auth
#發(fā)件人昵稱
jmail.addresser=XXX
3.2創(chuàng)建一個接口
/**
* \* Created with IntelliJ IDEA.
* \* User: 黃樹偉
* \* Date: 2017/10/24
* \* Time: 11:03
* \* To change this template use File | Settings | File Templates.
* \* Description:
* \
*/
public interface IJMailService {
/**
*
* @param mailTopic 郵件主題
* @param content 郵件內(nèi)容
* @throws Exception
*/
void sendEmail(String mailTopic,String content) throws Exception;
}
3.3實現(xiàn)類
import com.tclac.tclkt.service.IJMailService;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import javax.mail.Message.RecipientType;
import javax.mail.Session;
import javax.mail.Transport;
import javax.mail.internet.InternetAddress;
import javax.mail.internet.MimeMessage;
import java.util.Date;
import java.util.Properties;
/**
* \* Created with IntelliJ IDEA.
* \* User: 黃樹偉
* \* Date: 2017/10/24
* \* Time: 11:03
* \* To change this template use File | Settings | File Temlates.
* \* Description:
* \
*/
@Service
public class JMailServiceImpl implements IJMailService{
// 發(fā)件人的 郵箱 和 密碼(替換為自己的郵箱和密碼)
// PS: 某些郵箱服務(wù)器為了增加郵箱本身密碼的安全性结序,給 SMTP 客戶端設(shè)置了獨立密碼(有的郵箱稱為“授權(quán)碼”),
// 對于開啟了獨立密碼的郵箱, 這里的郵箱密碼必需使用這個獨立密碼(授權(quán)碼)障斋。
@Value("${jmail.myEmailAccount}")
public String myEmailAccount;
@Value("${jmail.myEmailPassword}")
public String myEmailPassword;
// 發(fā)件人郵箱的 SMTP 服務(wù)器地址, 必須準確, 不同郵件服務(wù)器地址不同, 一般(只是一般, 絕非絕對)格式為: smtp.xxx.com
// 網(wǎng)易163郵箱的 SMTP 服務(wù)器地址為: smtp.163.com
@Value("${jmail.myEmailSMTPHost}")
public String myEmailSMTPHost;
// 收件人郵箱(替換為自己知道的有效郵箱)
@Value("${jmail.receiveMailAccount}")
public String receiveMailAccount;
// 使用的協(xié)議名稱
@Value("${jmail.protocolName}")
public String protocolName;
// 使用的協(xié)議值
@Value("${jmail.protocolValue}")
public String protocolValue;
// 發(fā)件人的郵箱的 SMTP 服務(wù)器地址名稱
@Value("${jmail.hostName}")
public String hostName;
// 請求認證名稱
@Value("${jmail.authName}")
public String authName;
// 發(fā)件人昵稱
@Value("${jmail.addresser}")
public String addresser;
@Override
public void sendEmail(String mailTopic,String content) throws Exception {
// 1. 創(chuàng)建參數(shù)配置, 用于連接郵件服務(wù)器的參數(shù)配置
Properties props = new Properties(); // 參數(shù)配置
props.setProperty(protocolName, protocolValue); // 使用的協(xié)議(JavaMail規(guī)范要求)
props.setProperty(hostName, myEmailSMTPHost); // 發(fā)件人的郵箱的 SMTP 服務(wù)器地址
props.setProperty(authName, "true"); // 需要請求認證
// PS: 某些郵箱服務(wù)器要求 SMTP 連接需要使用 SSL 安全認證 (為了提高安全性, 郵箱支持SSL連接, 也可以自己開啟),
// 如果無法連接郵件服務(wù)器, 仔細查看控制臺打印的 log, 如果有有類似 “連接失敗, 要求 SSL 安全連接” 等錯誤,
// 打開下面 /* ... */ 之間的注釋代碼, 開啟 SSL 安全連接。
/*
// SMTP 服務(wù)器的端口 (非 SSL 連接的端口一般默認為 25, 可以不添加, 如果開啟了 SSL 連接,
// 需要改為對應(yīng)郵箱的 SMTP 服務(wù)器的端口, 具體可查看對應(yīng)郵箱服務(wù)的幫助,
// QQ郵箱的SMTP(SLL)端口為465或587, 其他郵箱自行去查看)
final String smtpPort = "465";
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.socketFactory.port", smtpPort);
*/
// 2. 根據(jù)配置創(chuàng)建會話對象, 用于和郵件服務(wù)器交互
Session session = Session.getDefaultInstance(props);
session.setDebug(true); // 設(shè)置為debug模式, 可以查看詳細的發(fā)送 log
// 3. 創(chuàng)建一封郵件
MimeMessage message = createMimeMessage(session, myEmailAccount, receiveMailAccount,mailTopic,content);
// 4. 根據(jù) Session 獲取郵件傳輸對象
Transport transport = session.getTransport();
// 5. 使用 郵箱賬號 和 密碼 連接郵件服務(wù)器, 這里認證的郵箱必須與 message 中的發(fā)件人郵箱一致, 否則報錯
//
// PS_01: 成敗的判斷關(guān)鍵在此一句, 如果連接服務(wù)器失敗, 都會在控制臺輸出相應(yīng)失敗原因的 log,
// 仔細查看失敗原因, 有些郵箱服務(wù)器會返回錯誤碼或查看錯誤類型的鏈接, 根據(jù)給出的錯誤
// 類型到對應(yīng)郵件服務(wù)器的幫助網(wǎng)站上查看具體失敗原因徐鹤。
//
// PS_02: 連接失敗的原因通常為以下幾點, 仔細檢查代碼:
// (1) 郵箱沒有開啟 SMTP 服務(wù);
// (2) 郵箱密碼錯誤, 例如某些郵箱開啟了獨立密碼;
// (3) 郵箱服務(wù)器要求必須要使用 SSL 安全連接;
// (4) 請求過于頻繁或其他原因, 被郵件服務(wù)器拒絕服務(wù);
// (5) 如果以上幾點都確定無誤, 到郵件服務(wù)器網(wǎng)站查找?guī)椭? //
// PS_03: 仔細看log, 認真看log, 看懂log, 錯誤原因都在log已說明垃环。
transport.connect(myEmailAccount, myEmailPassword);
// 6. 發(fā)送郵件, 發(fā)到所有的收件地址, message.getAllRecipients() 獲取到的是在創(chuàng)建郵件對象時添加的所有收件人, 抄送人, 密送人
transport.sendMessage(message, message.getAllRecipients());
// 7. 關(guān)閉連接
transport.close();
}
/**
* 創(chuàng)建一封只包含文本的簡單郵件
*
* @param session 和服務(wù)器交互的會話
* @param sendMail 發(fā)件人郵箱
* @param receiveMail 收件人郵箱
* @return
* @throws Exception
*/
private MimeMessage createMimeMessage(Session session, String sendMail, String receiveMail,String mailTopic,String content) throws Exception {
// 1. 創(chuàng)建一封郵件
MimeMessage message = new MimeMessage(session);
// 2. From: 發(fā)件人(昵稱有廣告嫌疑,避免被郵件服務(wù)器誤認為是濫發(fā)廣告以至返回失敗返敬,請修改昵稱)
message.setFrom(new InternetAddress(sendMail, addresser, "UTF-8"));
// 3. To: 收件人(可以增加多個收件人遂庄、抄送、密送)
InternetAddress[] addresses = new InternetAddress[3];
// addresses[0] = new InternetAddress(receiveMail, "siyuan", "UTF-8");
// addresses[1] = new InternetAddress("xxx@qq.com", "siyuan1", "UTF-8");
// addresses[2] = new InternetAddress("xxx@qq.com", "siyuan2", "UTF-8");
// 4. Subject: 郵件主題(標題有廣告嫌疑劲赠,避免被郵件服務(wù)器誤認為是濫發(fā)廣告以至返回失敗涛目,請修改標題)
message.setSubject(mailTopic, "UTF-8");
// 5. Content: 郵件正文(可以使用html標簽)(內(nèi)容有廣告嫌疑秸谢,避免被郵件服務(wù)器誤認為是濫發(fā)廣告以至返回失敗,請修改發(fā)送內(nèi)容)
message.setContent(content, "text/html;charset=UTF-8");
// 6. 設(shè)置發(fā)件時間
message.setSentDate(new Date());
// 7. 保存設(shè)置
message.saveChanges();
return message;
}
}