標籤:應該 pen 方法 def 如何 images img lda xid
在日常生活中,我們在一個網站中註冊一個賬戶時,往往在提交個人資訊後,網站還要我們通過手機或郵件來驗證,郵件的話大概會是下面這個樣子的:
使用者通過點選連結從而完成註冊,然後才能登入。
也許你會想,為什麼要這麼麻煩直接提交註冊不就行了嗎?這其中很大一部分原因是為了防止惡意註冊。接下來讓我們一起來使用最簡單的JSP+Servlet的方式來完成一個通過郵箱驗證註冊的小案例吧。
準備工作前提知識
動手實踐之前,你最好對以下知識有所瞭解:
- JSP和Servlet
- Maven
- MySQL
- c3p0
- SMTP協議和POP3協議
如果對郵件收發過程完全不瞭解的話,可以花三分鐘的時間到慕課網瞭解一下,講得算是非常清楚了,這裡就不贅述了。放張圖回憶一下:
郵件收發過程郵箱準備
在瞭解的上述內容之後,要實現這個案例,首先我們還得有兩個郵箱帳號,一個用來發送郵件,一個用來內送郵件。本案例使用QQ郵箱向163郵箱發送啟用郵件,因此需要登入QQ郵箱,在設定->賬戶面板中開啟POP3/SMTP服務,以允許我們通過第三方用戶端發送郵件:
還要注意的是,登入以下服務: POP3/IMAP/SMTP/Exchange/CardDAV/CalDAV服務時,需要用到授權碼而不是QQ密碼,授權碼是用於登入第三方郵件用戶端的專用密碼。因此我們需要獲得授權碼,以在後面的程式中使用。
好了,到此準備工作就差不多了,下面開始動手吧。
實現註冊Demo建立Maven工程
本次案例基於Maven,因此你要先建立一個Maven的Web工程,並引入相關依賴:
<dependencies> <!-- JavaEE依賴 --> <dependency> <groupId>javaee</groupId> <artifactId>javaee-api</artifactId> <version>5</version> <scope>test</scope> </dependency> <dependency> <groupId>taglibs</groupId> <artifactId>standard</artifactId> <version>1.1.2</version> </dependency> <!-- mysql驅動依賴 --> <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> <version>5.1.40</version> </dependency> <!-- c3p0依賴 --> <dependency> <groupId>c3p0</groupId> <artifactId>c3p0</artifactId> <version>0.9.1.2</version> </dependency> <!-- JavaMail相關依賴 --> <dependency> <groupId>javax.mail</groupId> <artifactId>mail</artifactId> <version>1.4.7</version> </dependency> <dependency> <groupId>javax.activation</groupId> <artifactId>activation</artifactId> <version>1.1.1</version> </dependency></dependencies>
建立資料庫表
接下來使用MySQL建立一張簡單的使用者表:
create table `user`( id int(11) primary key auto_increment comment ‘使用者id‘, username varchar(255) not null comment ‘使用者名稱‘, email varchar(255) not null comment ‘使用者郵箱‘, password varchar(255) not null comment ‘使用者密碼‘, state int(1) not null default 0 comment ‘使用者啟用狀態:0表示未啟用,1表示啟用‘, code varchar(255) not null comment ‘啟用碼‘)engine=InnoDB default charset=utf8;
其中要注意的地方是state欄位(用來判斷使用者帳號是否啟用)和code欄位(啟用碼)。
建立註冊頁面
使用JSP建立一個最簡單的註冊頁面(請自行忽略介面):
嗯,果然夠簡單。
主要的商務邏輯
先想一下,我們的整個流程應該是這樣的:
- 使用者填寫相關資訊,點擊註冊按鈕
- 系統先將使用者記錄儲存到資料庫中,其中使用者狀態為未啟用
- 系統發送一封郵件並通知使用者去驗證
- 使用者登入郵箱並點擊啟用連結
- 系統將使用者狀態更改為已啟用並通知使用者註冊成功
搞清楚了整個流程,實現起來應該就不難了。是我建立的包結構:
ps:完整代碼請見後文連結,這裡只討論主要的思路
首先是,使用者提交註冊資訊後,相應的servlet會將相關資訊傳給service層去處理,在service中需要做的就是講記錄儲存到資料庫中(調用dao層),然後再給使用者發送一封郵件,UserServiceImpl相關代碼如下:
public boolean doRegister(String userName, String password, String email) { // 這裡可以驗證各欄位是否為空白 //利用Regex(可改進)驗證郵箱是否符合郵箱的格式 if(!email.matches("^\\[email protected](\\w+\\.)+\\w+$")){ return false; } //產生啟用碼 String code=CodeUtil.generateUniqueCode(); User user=new User(userName,email,password,0,code); //將使用者儲存到資料庫 UserDao userDao=new UserDaoImpl(); //儲存成功則通過線程的方式給使用者發送一封郵件 if(userDao.save(user)>0){ new Thread(new MailUtil(email, code)).start();; return true; } return false;}
需要注意的是,應該建立一個線程去執行發送郵件的任務,不然被罵估計是免不了了。
資料庫的操作比較簡單,此處就不貼出來了,無非是將使用者記錄插到資料庫中。值得一提的是,此處使用c3p0來作為資料來源來替代DriverManager,在頻繁擷取釋放資料庫連接時效率會大大提高,c3p0最簡單的配置如下:
<?xml version="1.0" encoding="UTF-8"?><c3p0-config> <named-config name="mysql"> <property name="driverClass">com.mysql.jdbc.Driver</property> <property name="jdbcUrl">jdbc:mysql://127.0.0.1:3306/test1?useSSL=false</property> <property name="user">root</property> <property name="password">123456</property> <!-- 初始化時一個串連池嘗試獲得的串連數量,預設是3,大小應該在maxPoolSize和minPoolSize之間 --> <property name="initialPoolSize">5</property> <!-- 一個串連最大空閑時間(單位是秒),0意味著串連不會過時 --> <property name="maxIdleTime">30</property> <!-- 任何指定時間的最大串連數量 ,預設值是15 --> <property name="maxPoolSize">20</property> <!-- 任何指定時間的最小串連數量 ,預設值是3 --> <property name="minPoolSize">5</property> </named-config></c3p0-config>
提供一個工具類DBUtil以擷取,釋放串連:
<pre>
public class DBUtil {
private static ComboPooledDataSource cpds=null;
static{ cpds=new ComboPooledDataSource("mysql");}public static Connection getConnection(){ Connection connection=null; try { connection = cpds.getConnection(); } catch (SQLException e) { e.printStackTrace(); } return connection;}public static void close(Connection conn,PreparedStatement pstmt,ResultSet rs){ try { if(rs!=null){ rs.close(); } if(pstmt!=null){ pstmt.close(); } if(rs!=null){ rs.close(); } } catch (SQLException e) { e.printStackTrace(); } }
}
</pre>
要特別注意的一點是:即使是使用串連池,使用完Connection後調用close方法,當然這不意味著關閉與資料庫的TCP 串連,而是將串連還回到池中去,如果不close掉的話,這個串連將會一直被佔用,直到串連池中的串連耗盡為止。
使用JavaMail發送郵件
使用JavaMail發送郵件非常簡單,也是三步曲:
- 建立連線物件javax.mail.Session
- 建立郵件對象 javax.mail.Message
- 發送郵件
直接看代碼,詳細的注釋在代碼中,MailUtil代碼如下:
public class MailUtil implements Runnable { private String email;// 收件者郵箱 private String code;// 啟用碼 public MailUtil(String email, String code) { this.email = email; this.code = code; } public void run() { // 1.建立連線物件javax.mail.Session // 2.建立郵件對象 javax.mail.Message // 3.發送一封啟用郵件 String from = "[email protected]";// 寄件者電子郵箱 String host = "smtp.qq.com"; // 指定發送郵件的主機smtp.qq.com(QQ)|smtp.163.com(網易) Properties properties = System.getProperties();// 擷取系統屬性 properties.setProperty("mail.smtp.host", host);// 設定郵件伺服器 properties.setProperty("mail.smtp.auth", "true");// 開啟認證 try { //QQ郵箱需要下面這段代碼,163郵箱不需要 MailSSLSocketFactory sf = new MailSSLSocketFactory(); sf.setTrustAllHosts(true); properties.put("mail.smtp.ssl.enable", "true"); properties.put("mail.smtp.ssl.socketFactory", sf); // 1.擷取預設session對象 Session session = Session.getDefaultInstance(properties, new Authenticator() { public PasswordAuthentication getPasswordAuthentication() { return new PasswordAuthentication("[email protected]", "xxx"); // 寄件者郵箱帳號、授權碼 } }); // 2.建立郵件對象 Message message = new MimeMessage(session); // 2.1設定寄件者 message.setFrom(new InternetAddress(from)); // 2.2設定接收人 message.addRecipient(Message.RecipientType.TO, new InternetAddress(email)); // 2.3設定郵件主題 message.setSubject("帳號啟用"); // 2.4設定郵件內容 String content = "<html><head></head><body><h1>這是一封啟用郵件,啟用請點擊以下連結</h1><h3><a href=‘http://localhost:8080/RegisterDemo/ActiveServlet?code=" + code + "‘>http://localhost:8080/RegisterDemo/ActiveServlet?code=" + code + "</href></h3></body></html>"; message.setContent(content, "text/html;charset=UTF-8"); // 3.發送郵件 Transport.send(message); System.out.println("郵件成功發送!"); } catch (Exception e) { e.printStackTrace(); } }}
ps:需要把上面的帳號、授權碼進行相應修改。
完成後,再有使用者提交註冊資訊時,應該就能收到驗證郵件了:
使用者點選連結後,我們要做的工作就是根據code(可以利用UUID產生)更改資料庫中相應使用者的狀態,然後提示使用者註冊結果了。
總結
簡單介紹了如何使用JavaMail完成了一個帶郵箱驗證的註冊案例,當然在實際開發中還有許多細節要注意,例如對使用者提交資訊的校正,密碼進行加密等,此處的簡單案例並未詳盡處理這些細節。
代碼
SnDragon
連結:https://www.jianshu.com/p/8f8d7a46888f
來源:簡書
簡書著作權歸作者所有,任何形式的轉載都請聯絡作者獲得授權並註明出處。
郵箱認證流程