利用郵箱進行輔助註冊
一、傳送郵件的原理
在瞭解其原理之前,先要知道兩個協議,SMTP和POP3
SMTP:Simple Mail Transfer Protocol,即簡單郵件傳輸協議,傳送郵件的協議,預設埠,25
POP3:Post Office Protocol 3,即郵局協議,接收郵件的協議,預設埠,110
知道了這兩個協議,下面來說說郵件傳送和接收的原理圖,分兩種,相同郵件(QQ郵箱給QQ郵箱)和不同郵件(QQ郵箱給163郵箱)是不一樣的。
解釋:
為了方便起見,將新浪郵箱,[email protected]稱為使用者A,將搜狐郵箱,[email protected] 稱為使用者B
使用者A(新浪郵箱,[email protected])給使用者B(搜狐郵箱,[email protected])傳送一封郵件,那麼整個過程就為圖中的實線部分,使用者A通過OutLook(瀏覽器或者客戶端)登入自己的郵箱帳號,編寫郵件,使用Smtp協議傳送給Sina的郵件伺服器中的Smtp伺服器(專門用來發送的伺服器),然後在通過SMTP協議,傳輸給Sohu的郵件伺服器中的Smtp伺服器,然後通過Sohu的Smtp伺服器將郵件傳送給使用者B的儲存裝置進行儲存(每個使用者都會有一個儲存空間用來儲存郵件的),到這裡,使用者A就相當於傳送成功了,因為已經到達了目的地,如果B使用者需要檢視郵件內容,必須通過POP3伺服器將從自己的儲存裝置中拿到,然後返回到瀏覽器或者客戶端中顯示。
使用者B給使用者A傳送一封郵件,那麼整個過程就為圖中的虛線部分,是和A給B發一樣的步驟
使用者A給一個同樣使用新浪郵箱的使用者C傳送一封郵件,那麼其過程就簡單的多了,先通過Smtp伺服器,然後smtp伺服器會將其傳送到使用者C的儲存裝置上,A傳送郵件就成功了,使用者C要顯示自己郵箱中的郵件,那麼就通過POP3伺服器從自己儲存裝置中拿取所有郵件進行檢視。
二、通過Java程式碼實現傳送郵件
2.1、準備jar包
核心:mail.jar
依賴:activation.jar, 郵件需要傳送附件時使用
使用QQ郵箱傳送郵件
2.3.1、首先在QQ郵箱中註冊一個帳號。有的話就省略這一步
2.3.2、進行三大步,建立連線、建立訊息,傳送訊息
確定連線位置
//傳送方
String myAccount = "[email protected]";
//授權碼
String myPass = "xtevddbazoshdfcd";
//發件人 郵箱的 SMTP 伺服器地址
String SMTPHost = "smtp.qq.com";
//組成 properties
Properties prop = new Properties();
prop.setProperty("mail.transport.protocol", "smtp");//設定協議型別
prop.setProperty("mail.smtp.host", SMTPHost);//定義發件人的郵箱伺服器地址
prop.setProperty("mail.smtp.auth", "true");//設定請求驗證
QQ郵箱的SSL加密
MailSSLSocketFactory sf = new MailSSLSocketFactory();
sf.setTrustAllHosts(true);
prop.put("mail.smtp.ssl.enable", "true");
prop.put("mail.smtp.ssl.socketFactory", sf);
建立連線
//1.Session物件 建立會話 用於和郵箱伺服器進行互動
Session session = Session.getDefaultInstance(prop);
//設定debug模式 可以檢視詳細傳送資訊 可略
session.setDebug(true);
Transport tran = session.getTransport();
//連線伺服器 確認傳送方 是否授權
tran.connect(myAccount, myPass);
建立訊息
private static MimeMessage createMsg(Session session, String myAccount, User user) {
//使用session物件 獲取待發送的郵件資訊
MimeMessage message = new MimeMessage(session);
//3.設定發件人 收件人 標題 郵件內容 附件 傳送時間等等
try {
//3.1發件人 from
message.setFrom(new InternetAddress(myAccount, "小米", "utf-8"));
//3.2收件人 to 支援可以新增多個收件人 | 抄送 | 密送 如果想要傳送給多個人 可以重複下面程式碼多次
/*
* MimeMessage.RecipientType.TO 傳送
* MimeMessage.RecipientType.CC 抄送
* MimeMessage.RecipientType.BCC 密送
* 比如A要給B發郵件,但是A覺得有必要給要讓C也看看其內容,就在給B發郵件時,
* 將郵件內容抄送給C,那麼C也能看到其內容了,但是B也能知道A給C抄送過該封郵件
* 而如果是暗送(密送)給C的話,那麼B就不知道A給C傳送過該封郵件。比如A要給B發郵件,但是A覺得有必要給要讓C也看看其內容,就在給B發郵件時,
* 將郵件內容抄送給C,那麼C也能看到其內容了,但是B也能知道A給C抄送過該封郵件
* 而如果是暗送(密送)給C的話,那麼B就不知道A給C傳送過該封郵件。
* */
message.setRecipient(MimeMessage.RecipientType.TO, new InternetAddress(user.getEmail(), user.getUsername(), "utf-8"));
//3.3生成郵件主題
message.setSubject("小米商城賬號啟用郵件","utf-8");
//這裡如果你本地有虛擬機器的話,ip會很奇怪,而且qq郵箱因為安全問題,不能用localhost
// Inet4Address.getLocalHost().getHostAddress();
//String ip ="127.0.0.1";
String url = "http://127.0.0.1:8080/myshop/user?method=active&c="+Base64Utils.encode(user.getCode());
//設定郵件正文 setContent 可以使用html標籤
message.setContent(user.getUsername()+",你好<br>歡迎註冊小米商城! 請點選連結進行啟用:<a href='"+url+"'>點選進行啟用</a>","text/html;charset=utf-8");
//設定郵件的傳送時間 是立即傳送
message.setSentDate(new Date());
//儲存設定
message.saveChanges();
} catch (MessagingException e) {
e.printStackTrace();
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
return message;
}
}
傳送訊息
//傳送郵件 將message 物件 傳給 Transport 物件 將郵件傳送出去
//引數1 要發的內容 引數2 要給哪些人發
//message.getAllRecipients() 獲取到所有的收件人 | 抄送 | 密送
tran.sendMessage(message, message.getAllRecipients());
//關閉連線
tran.close();
授權碼的解釋
什麼是授權碼?這個很簡單,如果你不是在qq的郵箱網址中登入的,而是在一些第三方客戶端中登入郵箱帳號密碼,那麼就必須進行授權,來獲取一個授權碼,使用該授權碼在第三方客戶端中進行登入。而該授權碼就相當於我們的密碼了,帳號是不變的,也就是我們說我們在java程式碼中想登入郵箱,那麼就必須使用授權碼進行登入。如果獲取授權碼呢?
登入之後肯定顯示的是首頁,在首頁中有一個設定,點選設定,在左面就會顯示一系列的設定選項,點選客戶端授權密碼,就會顯示如圖中所示,讓其設定客戶端授權碼,如果沒開啟的話,預設就是關閉的,然後在按照步驟點選開啟,一步步設定,就能得到授權碼。
登入之後肯定顯示的是首頁,在首頁中有一個設定,點選設定,在左面就會顯示一系列的設定選項,點選客戶端授權密碼,就會顯示如圖中所示,讓其設定客戶端授權碼,如果沒開啟的話,預設就是關閉的,然後在按照步驟點選開啟,一步步設定,就能得到授權碼。
如果不使用授權碼,那麼java程式會報錯,報錯資訊是驗證失敗,說明帳號密碼不正確,此時就是密碼不正確,因為這裡密碼應該寫授權碼
完整程式碼
/*
* 1.首先需要獲取傳送郵件的Session物件
* Session session = Session.getDefaultInstance(Properties prop)
* 2.使用session物件 獲取待發送的郵件資訊
* MimeMessage mime = new MimeMessage(session)
* 3.設定發件人 收件人 標題 郵件內容 附件 傳送時間等等
* 4.利用Transport 傳送郵件
* */
public class EmailUtils {
public static void sendEmail(User user) throws GeneralSecurityException {
//傳送方
String myAccount = "[email protected]";
//授權碼
String myPass = "xtevddbazoshdfcd";
//發件人 郵箱的 SMTP 伺服器地址
String SMTPHost = "smtp.qq.com";
//組成 properties
Properties prop = new Properties();
prop.setProperty("mail.transport.protocol", "smtp");//設定協議型別
prop.setProperty("mail.smtp.host", SMTPHost);//定義發件人的郵箱伺服器地址
prop.setProperty("mail.smtp.auth", "true");//設定請求驗證
//QQ郵箱的SSL加密。
MailSSLSocketFactory sf = new MailSSLSocketFactory();
sf.setTrustAllHosts(true);
prop.put("mail.smtp.ssl.enable", "true");
prop.put("mail.smtp.ssl.socketFactory", sf);
//1.Session物件 建立會話 用於和郵箱伺服器進行互動
Session session = Session.getDefaultInstance(prop);
//設定debug模式 可以檢視詳細傳送資訊 可略
session.setDebug(true);
//2.建立方法 用來組成一封完整的郵件
//引數 session(引數配置), myAccount 傳送方 , user.getEmail() 接收方
MimeMessage message = createMsg(session,myAccount,user);
//4.利用Transport 傳送郵件
try {
Transport tran = session.getTransport();
//連線伺服器 確認傳送方 是否授權
tran.connect(myAccount, myPass);
//傳送郵件 將message 物件 傳給 Transport 物件 將郵件傳送出去
//引數1 要發的內容 引數2 要給哪些人發
//message.getAllRecipients() 獲取到所有的收件人 | 抄送 | 密送
tran.sendMessage(message, message.getAllRecipients());
//關閉連線
tran.close();
} catch (MessagingException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
private static MimeMessage createMsg(Session session, String myAccount, User user) {
//使用session物件 獲取待發送的郵件資訊
MimeMessage message = new MimeMessage(session);
//3.設定發件人 收件人 標題 郵件內容 附件 傳送時間等等
try {
//3.1發件人 from
message.setFrom(new InternetAddress(myAccount, "小米", "utf-8"));
//3.2收件人 to 支援可以新增多個收件人 | 抄送 | 密送 如果想要傳送給多個人 可以重複下面程式碼多次
/*
* MimeMessage.RecipientType.TO 傳送
* MimeMessage.RecipientType.CC 抄送
* MimeMessage.RecipientType.BCC 密送
* */
message.setRecipient(MimeMessage.RecipientType.TO, new InternetAddress(user.getEmail(), user.getUsername(), "utf-8"));
//3.3生成郵件主題
message.setSubject("小米商城賬號啟用郵件","utf-8");
//這裡如果你本地有虛擬機器的話,ip會很奇怪,而且qq郵箱因為安全問題,不能用localhost
// Inet4Address.getLocalHost().getHostAddress();
//String ip ="127.0.0.1";
String url = "http://127.0.0.1:8080/myshop/user?method=active&c="+Base64Utils.encode(user.getCode());
//設定郵件正文 setContent 可以使用html標籤
message.setContent(user.getUsername()+",你好<br>歡迎註冊小米商城! 請點選連結進行啟用:<a href='"+url+"'>點選進行啟用</a>","text/html;charset=utf-8");
//設定郵件的傳送時間 是立即傳送
message.setSentDate(new Date());
//儲存設定
message.saveChanges();
} catch (MessagingException e) {
e.printStackTrace();
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
return message;
}
}
總結
上面使用QQ郵箱傳送郵件, 其他的一些郵箱伺服器,應該也類似,就算有也是一些細微的區別,就好比上面QQ郵箱需要使用SSL加密,而163不需要一樣,遇到錯誤可以百度自己解決一下。然後必須註明一點,上面的傳送郵件的前提是,必須要聯網,如果不能聯網,那就不能夠成功傳送郵件,並且會報異常。