在javaweb中實現(xiàn)發(fā)送簡單郵件
前言
當我們在一個網站中進行注冊賬戶成功后,通常會收到一封來自該網站的郵件。郵件中顯示我們剛剛申請的賬戶和密碼以及一些其他的廣告信息。在上一篇中用Java實現(xiàn)了發(fā)送qq郵件的功能,今天我們來實現(xiàn)一個這樣的功能,用戶注冊成功后,網站將用戶的注冊信息(賬號和密碼等)以Email的形式發(fā)送到用戶的注冊郵箱當中。
a、電子郵件協(xié)議
電子郵件在網絡中傳輸和網頁一樣需要遵從特定的協(xié)議,常用的電子郵件協(xié)議包括 SMTP,POP3,IMAP。其中郵件的創(chuàng)建和發(fā)送只需要用到 SMTP協(xié)議,所以本文也只會涉及到SMTP協(xié)議。SMTP 是 Simple Mail Transfer Protocol 的簡稱,即簡單郵件傳輸協(xié)議。
b、JavaMail
我們平時通過 Java 代碼打開一個 http 網頁鏈接時,通??梢允褂靡呀泴?http 協(xié)議封裝好的 HttpURLConnection 類來快速地實現(xiàn)。Java 官方也提供了對電子郵件協(xié)議封裝的 Java 類庫,就是JavaMail,但并沒有包含到標準的 JDK 中,需要我們自己去官方下載。
1、準備工作
需要兩個jar包?activation.jar
?/?mail.jar

所要用到的授權碼:qq郵件登錄 -> 設置 -> 賬戶

其中
SMTP是接收協(xié)議
POP3是接收協(xié)議
2、 編寫實體類
public class User {
? ?
private String name;
? ?
private String password;
? ?
private String email;
? ?
public User(String name, String password, String email) {
? ? ? ?
this.name = name;
? ? ? ?
this.password = password;
? ? ? ?
this.email = email;
? ?
}
? ?
//省略get/set和toString方法...?
}
3、編寫靜態(tài)頁面
index.jsp
:一個簡單的表單 包含用戶名、密碼、郵箱
<%@ page contentType="text/html;charset=UTF-8" language="java" %>?
<html>
?
<head>
? ?
<title>$Title$</title>
?
</head>
?
<body>
?
<form action="${pageContext.request.contextPath}/mail.do" method="post">
? ?用戶名: <input type="text" name="username" value="賬戶">
? ?
<br>
? ?
密碼: <input type="password" name="password" value="密碼">
? ?
<br>
? ?
郵箱: <input type="text" name="email" value="郵箱">
? ?
<br>
? ?
<input type="submit" value="注冊">
?
</form>
?
</body>?
</html>
4、編寫發(fā)送郵件的工具類
發(fā)送郵件的步驟
1.創(chuàng)建定義整個應用程序所需的環(huán)境信息的sessio對象
2.通過session得到transport對象
3.使用郵箱的用戶名和授權碼連上郵件服務器
4.創(chuàng)建郵件
5.發(fā)送郵件
這里用到了多線程,因為發(fā)送郵件是需要時間去連接郵箱的服務器,若不使用多線程,則會卡在提交的網頁中不斷加載直至響應?使用多線程可以異步處理,提高用戶的體驗度
public class SendMail extends Thread {
? ?
private String from = "發(fā)件人郵箱";
? ?
private String username = "發(fā)件人用戶名";
? ?
private String password = "授權碼";
? ?
private String host = "smtp.qq.com"; //QQ郵箱的主機協(xié)議
? ?
private User user;
? ?
public SendMail(User user) {
? ? ? ?
this.user = user;
? ?}
? ?
public void run() {
? ? ? ?
Transport ts = null;
? ? ? ?
try {
? ? ? ? ? ?
Properties prop = new Properties();
? ? ? ? ? ?prop.setProperty("mail.host",host);
? ? ? ? ? ?prop.setProperty("mail.transport.protocol","smtp");
? ? ? ? ? ?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);
? ? ? ? ? ?
//使用JavaMail發(fā)送郵件的5個步驟
? ? ? ? ? ?
//1.創(chuàng)建定義整個應用程序所需的環(huán)境信息的sessio對象
? ? ? ? ? ?
Session session = Session.getDefaultInstance(prop, new Authenticator() {? ? ? ? ? ? ? ? ?
@Override
? ? ? ? ? ? ? ?protected PasswordAuthentication getPasswordAuthentication()
?{ ? ? ? ? ? ? ? ? ? ?return new PasswordAuthentication(username,password); ? ? ? ? ? ? ?
??} ? ? ? ? ? ?}); ? ? ? ? ??
?session.setDebug(true);
//開啟debug模式 看到發(fā)送的運行狀態(tài) ? ? ? ? ? ?
//2.通過session得到transport對象 ? ? ? ? ? ?
ts = session.getTransport(); ? ? ? ? ? ?
//3.使用郵箱的用戶名和授權碼連上郵件服務器 ? ? ? ? ? ?ts.connect(host,username,password); ? ? ? ? ? ?
//4.創(chuàng)建純文本的簡單郵件 ? ? ? ? ??
?MimeMessage message = new MimeMessage(session); ? ? ? ? ? ?message.setSubject("只包含文本的普通郵件");//郵件主題 ? ? ? ? ? ?message.setFrom(new InternetAddress(from));// 發(fā)件人 ? ? ? ? ? ?message.setRecipient(Message.RecipientType.TO,new InternetAddress(user.getEmail()));//收件人 ? ? ? ? ? ?
String info = "注冊成功!你的賬號信息為: username = " + user.getName() + "password = " + user.getPassword(); ? ? ? ? ? ?
message.setContent("<h1 style='color: red'>" + info + "</h1>","text/html;charset=UTF-8");//郵件內容 ? ? ? ? ? ?message.saveChanges();//保存設置 ? ? ? ? ? ?
//5.發(fā)送郵件 ? ? ? ? ? ?
ts.sendMessage(message,message.getAllRecipients()); ? ? ? ?
} catch (GeneralSecurityException e)?
{ ? ? ? ? ? ?e.printStackTrace(); ? ? ? ?
} catch (MessagingException e) { ? ? ? ? ? ?
e.printStackTrace(); ? ? ? ?
} finally { ? ? ? ? ? ?//關閉連接 ? ? ? ? ? ?
try { ? ? ? ? ? ? ? ?ts.close(); ? ? ? ? ? ?
} catch (MessagingException e) { ? ? ? ? ? ? ? ?
e.printStackTrace(); ? ? ? ? ? ?
} ? ? ? ?
} ? ?
}?
}
5、編寫處理請求的Servlet以及注冊Servlet
public class MailServlet extends HttpServlet {
? ?
@Override
? ?protected void doGet(HttpServletRequest req, HttpServletResponse resp)?
throws ServletException, IOException {
? ? ? ?//獲取前端數據
? ? ? ?
String username = req.getParameter("username");
? ? ? ?
String password = req.getParameter("password");
? ? ? ?
String email = req.getParameter("email");
? ? ? ?//封裝成一個User對象
? ? ? ?User user = new User(username,password,email);
? ? ? ?
SendMail send = new SendMail(user);
? ? ? ?
send.start();//啟動線程
? ? ? ?
req.setAttribute("message","已發(fā)送 請等待");
? ? ? ?req.getRequestDispatcher("info.jsp").forward(req,resp);//發(fā)送成功跳轉到提示頁面
? ?}
? ?
@Override
? ?protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
? ? ? ?doGet(req, resp);
? ?
}?
}
<?xml version="1.0" encoding="UTF-8"?>?
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
? ? ? ? xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
? ? ? ? xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd"
? ? ? ? version="4.0">
? ?<servlet>
? ? ? ?
<servlet-name>mail</servlet-name>
? ? ? ?
<servlet-class>com.xiaoyao.servlet.MailServlet</servlet-class>
? ?</servlet>
? ?
<servlet-mapping>
? ? ? ?
<servlet-name>mail</servlet-name>
? ? ? ?
<url-pattern>/mail.do</url-pattern>
? ?
</servlet-mapping>
</web-app>
測試ok!

補充:
工作中我用的是JavaMail 1.6.2的版本遇到過以下這個問題

這個問題就是沒有使用授權碼引起的,需要去發(fā)件人郵箱設置開啟授權碼;
1、怎么獲取授權碼?
先進入設置,帳戶頁面找到入口,按照以下流程操作。
(1)點擊“開啟”

(2)驗證密保

(3)獲取授權碼

總結:項目中可能會遇到的問題
1、使用JavaMail發(fā)送郵件時發(fā)現(xiàn),將郵件發(fā)送到sina或者sohu的郵箱時,不一定能夠馬上收取得到郵件,總是有延遲,有時甚至會延遲很長的時間,甚至會被當成垃圾郵件來處理掉,或者干脆就拒絕接收,有時候為了看到郵件發(fā)送成功的效果
2、在執(zhí)行到 message.saveChanges(); 方法報錯無法進行保存設置,也有可能時你的mail版本較低造成的。
在書寫 File file = new File(); 時注意修改正確的路徑,也可以寫在form表單里用file進行傳值,主題和內容也寫在了方法里因人而異如果其他需求可以需改參數進行傳值。
3、在執(zhí)行到 File file = new File(“D:\Chat_Software\sky.JPG”);時出現(xiàn)錯誤,之前寫的時xlsx文件,測試期間可以對.xls,jpg,文本,.doc文件進行發(fā)送。發(fā)送xlsx文件時出現(xiàn)報錯。 問題解決方案: .xls文件擴展名對應的是Microsoft Office EXCEL 2003及以前的版本。 .xlsx文件擴展名對應的是Microsoft Office EXCEL 2007及后期的版本。 有可能時你下載的mai不是1.6以上版本的,建議下載1.6以上版本的mail
