我們放假啦,前幾天瘋狂復習,現在又可以再次投入到代碼中啦,這是我的第一篇博客園博客耶嘻嘻,希望大家喜歡!(本人也只是個大二的小白一枚,一同進步和成長叭)
廢話不多說,我們要實現的功能是:注冊時對用戶輸入的郵箱進行驗證,包括 ①郵箱存不存在和 ②郵箱是否是用戶的郵箱 兩個驗證
我們分為前端和后端來實現:
前期准備
1. pom.xml文件中引入相關的依賴(發送郵箱用的依賴):
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-mail</artifactId> </dependency>
2. 引入相關js和css文件:
① 郵箱驗證要使用到的jquery.cookie.js:(作用后面會講哈)
下載地址:http://plugins.jquery.com/cookie/
下載完后放到相應的文件夾里,譬如我是這樣放的:
② me.css文件(不引入也可以喲,這只是讓頁面顯示在中間,並不影響功能)
1 .m-container-small { 2 max-width: 60em !important; 3 margin: auto !important; 4 } 5 .m-padded-tb-massive { 6 padding-top: 5em !important; 7 padding-bottom: 5em !important; 8 }
基本的前端(繼續完善的前端在下一篇,敬請期待)
1. html代碼:(注意要修改一下js文件的相對路徑,改成你自己的【第76行】)
(引入了css的小伙伴同時要改一下me.css的相對路徑哈【第9行】)
1 <!DOCTYPE html> 2 <html lang="en" xmlns:th="http://www.w3.org/1999/xhtml"> 3 <head> 4 <meta charset="UTF-8"> 5 <meta name="viewport" content="width=device-width,initial-scale=1.0"> 6 <title>博客游客注冊</title> 7 8 <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/semantic-ui@2.4.2/dist/semantic.min.css"> 9 <link rel="stylesheet" href="../../static/css/me.css"> 10 </head> 11 <body> 12 <br><br><br> 13 <div class="m-container-small m-padded-tb-massive" style="max-width: 30em !important;"> 14 <div class="ui container"> 15 <div class="ui middle aligned center aligned grid"> 16 17 <div class="column"> 18 <div class="ui negative message" th:unless="${#strings.isEmpty(message)}"> 19 <i class="close icon"></i> 20 <div class="header"> 21 校驗失敗 22 </div> 23 <p th:text="${message}"></p> 24 </div> 25 <h2 class="ui teal image header"> 26 <div class="content"> 27 游客注冊 28 </div> 29 </h2> 30 <form class="ui large form" method="post" action="#" th:action="@{/tourist/register}"> 31 <div class="ui segment"> 32 <div class="field"> 33 <div class="ui left icon input"> 34 <i class="user icon"></i> 35 <input type="text" id="username" name="username" placeholder="用戶名" 36 onchange="isUsernameUnique(this)"> 37 </div> 38 </div> 39 <div class="field"> 40 <div class="ui left icon input"> 41 <i class="lock icon"></i> 42 <input type="password" name="password" placeholder="密碼"> 43 </div> 44 </div> 45 <div class="field"> 46 <div class="ui left icon input"> 47 <i class="mail icon"></i> 48 <input type="text" name="email" id="email" placeholder="郵箱"> 49 <input type="button" id="getcode" class="ui grey label" value="獲取驗證碼"> 50 </div> 51 52 </div> 53 <div class="code field" style="display:none" > 54 <div class="ui left icon input"> 55 <i class="check square outline icon"></i> 56 <input type="text" name="identify" id="identify" placeholder="驗證碼"> 57 </div> 58 </div> 59 <button class="ui fluid large teal submit button" id="register-btn">注 冊</button> 60 </div> 61 <div id="isRepeat"></div> 62 <div class="ui error mini message"></div> 63 64 </form> 65 66 67 </div> 68 69 </div> 70 71 </div> 72 </div> 73 74 75 <script src="https://code.jquery.com/jquery-3.1.1.min.js" crossorigin="anonymous"></script> 76 <script type="text/javascript" src="../../static/js/jquery.cookie.js" ></script> 77 <script src="https://cdn.jsdelivr.net/npm/semantic-ui@2.4.2/dist/semantic.min.js"></script> 78 </body> 79 </html>
2. 界面展示
現在我們已經擁有一個靜態頁面啦,接下來的工作是讓它動起來
1. 在用戶點擊“獲取驗證碼”的時候,判斷郵箱位置是否為空,若為空,則不作任何操作
代碼如下:
1 $('#getcode').click(function(){ 2 3 //判斷郵箱位置是否為空 4 var email = $("#email").val(); 5 if(email==""){ 6 return; 7 } 8 9 });
2. 不為空的時候我們就要把用戶的郵箱發給后端,讓后端進行郵箱的存在性檢查以及發送
這時候要用到的技術是ajax:
$.ajax({ //url路徑 url: "http://localhost:8080/tourist/sendEmail", //data請求數據 data: {"email": email}, //dataType json type: "post", //回調函數 success: function (data) { //回調函數 data 返回流 if (data == "failure") { alert("發送失敗"); } else if (data=="false"){ alert("目標郵箱不存在,請檢查你的郵箱是否正確"); } // else{ // } } });
合並上面兩個代碼,結果如下:
$('#getcode').click(function(){ //發送驗證碼 var email = $("#email").val(); if(email==""){ return; } alert("驗證碼已發送,請及時查看你的郵箱"); $(".code").toggle(); //ajax實現后台郵箱的發送 $.ajax({ //url路徑 url: "http://localhost:8080/tourist/sendEmail", //data請求數據 data: {"email": email}, //dataType json type: "post", //回調函數 success: function (data) { //回調函數 data 返回流 if (data == "failure") { alert("發送失敗"); } else if (data=="false"){ alert("目標郵箱不存在,請檢查你的郵箱是否正確"); } // else{ // } } }); });
最基本的前端已經完成啦,我們現在來看后端:
后端的實現
1. controller的命名與位置:
①名字你可以隨便起,我起的是RegisterController
②位置我是新建了一個web文件夾,然后在web文件夾下新建了一個子文件夾tourist,在這個文件夾中放着我的控制器
(由於這是我博客系統的一部分功能,所以里面有很多很多代碼,我碼掉了,如果大家喜歡我的文章,我就會繼續分享一些實用的有關博客的功能唷)
2. html代碼:
(我命名為register.html,並且放在了templates文件里的子文件tourist下
)
//import com.lrm.util.MD5Utils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Value; import org.springframework.mail.MailSendException; import org.springframework.mail.SimpleMailMessage; import org.springframework.mail.javamail.JavaMailSender; import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.*; import org.springframework.web.servlet.mvc.support.RedirectAttributes; import javax.servlet.http.HttpSession; import java.text.SimpleDateFormat; import java.util.Calendar; import java.util.HashMap; import java.util.Map; import java.util.Random; @Controller @RequestMapping("/tourist") public class RegisterController { @Autowired private UserService userService; private final Logger logger = LoggerFactory.getLogger(this.getClass()); @Value("${mail.fromMail.sender}") private String sender;// 發送者 @Autowired private JavaMailSender javaMailSender; private Map<String, Object> resultMap = new HashMap<>(); @GetMapping("/register") public String register() { return "tourist/register"; } @RequestMapping("/sendEmail") //轉換json數據 @ResponseBody @ResponseBody public String sendEmail(String email) { SimpleMailMessage message = new SimpleMailMessage(); String code = VerifyCode(6); //隨機數生成6位驗證碼 message.setFrom(sender); message.setTo(email); message.setSubject("博客系統");// 標題 message.setText("【博客系統】你的驗證碼為:"+code+",有效時間為5分鍾(若不是本人操作,可忽略該條郵件)");// 內容 try { javaMailSender.send(message); logger.info("文本郵件發送成功!"); saveCode(code); return "success"; }catch (MailSendException e){ logger.error("目標郵箱不存在"); return "false"; } catch (Exception e) { logger.error("文本郵件發送異常!", e); return "failure"; } } private String VerifyCode(int n){ Random r = new Random(); StringBuffer sb =new StringBuffer(); for(int i = 0;i < n;i ++){ int ran1 = r.nextInt(10); sb.append(String.valueOf(ran1)); } // System.out.println(sb); return sb.toString(); } //保存驗證碼和時間 private void saveCode(String code){ SimpleDateFormat sf = new SimpleDateFormat("yyyyMMddHHmmss"); Calendar c = Calendar.getInstance(); c.add(Calendar.MINUTE, 5); String currentTime = sf.format(c.getTime());// 生成5分鍾后時間,用戶校驗是否過期 String hash = MD5Utils.code(code);//生成MD5值 resultMap.put("hash", hash); resultMap.put("tamp", currentTime); } }
思路:先隨機生成一串驗證碼,然后通過郵箱發送給用戶輸入的郵箱號,通過捕獲異常來判斷用戶輸入的郵箱是否存在
用到的小技術:里面用到了MD5加密,即生成驗證碼時,將驗證碼和發送時間通過加密技術進行加密,然后保存到Map對象中(用於后面與用戶輸入的驗證碼及時間相比對,來判斷用戶驗證碼輸入是否正確,以及驗證碼是否過期)
所以這里我們還需要引入一下MD5加密工具(或者你可以使用springboot自帶的加密功能,具體的可自行查閱)
MD5Utils的代碼如下:
import java.security.MessageDigest; import java.security.NoSuchAlgorithmException; public class MD5Utils { /** * MD5加密類 * * @param str 要加密的字符串 * @return 加密后的字符串 */ public static String code(String str) { try { MessageDigest md = MessageDigest.getInstance("MD5"); md.update(str.getBytes()); byte[] byteDigest = md.digest(); int i; StringBuffer buf = new StringBuffer(""); for (int offset = 0; offset < byteDigest.length; offset++) { i = byteDigest[offset]; if (i < 0) i += 256; if (i < 16) buf.append("0"); buf.append(Integer.toHexString(i)); } //32位加密 return buf.toString(); // 16位的加密 //return buf.toString().substring(8, 24); } catch (NoSuchAlgorithmException e) { e.printStackTrace(); return null; } } public static void main(String[] args) { System.out.println(code("123")); } }
(這個引入之后就可以在上面的controller報錯的地方引入相應的包啦(*^▽^*)【報錯的地方就是因為這個包沒引入】)
這樣發送驗證碼的前后端我們基本都寫好啦,是不是躍躍欲試呢,哈哈
放心,你馬上就可以開始運行了,我們還差最后一個工作,就是配置我們的application.properties
##根據自己的情況填寫 ##郵箱服務器地址 ##QQ smtp.qq.com ##sina smtp.sina.cn ##aliyun smtp.aliyun.com ##163 smtp.163.com spring.mail.host=smtp.qq.com ##郵箱用戶名 spring.mail.username=362517658@qq.com ##郵箱密碼(注意:QQ郵箱應該使用授權碼) spring.mail.password=******** ##編碼格式 spring.mail.default-encoding=UTF-8 ##發送郵件地址 mail.fromMail.sender=362517658@qq.com ##接收郵件地址 mail.fromMail.receiver=362517658@qq.com
注意!!里面的郵箱密碼,不是你的qq密碼,而是郵箱里的授權碼,不明白的可看下獲取授權碼步驟:
① 點擊設置
② 選擇“賬戶”
③ 下拉到圖中所示位置,選擇前兩個任意一個打開就行(我這里已經打開,沒有打開的小伙伴上面會有“打開”按鈕的選擇),根據它的指引最后可以獲得一串16位的授權碼,這個授權碼就是我們要的
噠啦啦啦,回到正題:現在讓我們來測試一下吧!
①點擊“獲取驗證碼”,跳出驗證碼框
② 輸入一個不存在的郵箱號
(這里的“59秒后可重新獲取”是我們后面要實現的功能,大家這里顯示的還是“獲取驗證碼”哈)
③ 填寫正確的郵箱地址
成功收到郵箱啦嘻嘻
發送郵箱驗證碼我們已經成功實現,現在我們要驗證一下用戶輸入的驗證碼是否和我們發送的一樣(你就快要完成啦,堅持就是勝利!!!!)
這里是點擊“注冊”時,我們進行郵箱驗證碼的判斷
前端我們是已經加過表單的跳轉位置了,
所以我們現在就來做相應的后端:
直接上后端代碼:(加在controller(我們的后端代碼)里)
@PostMapping("/register") public String login(@RequestParam String username, @RequestParam String password, @RequestParam String email, @RequestParam String identify,RedirectAttributes attributes, User user) { if (resultMap.size() ==0){ return "tourist/register"; } //判斷驗證碼是否正確 String requestHash = resultMap.get("hash").toString(); String tamp = resultMap.get("tamp").toString(); SimpleDateFormat sf = new SimpleDateFormat("yyyyMMddHHmmss");//當前時間 Calendar c = Calendar.getInstance(); String currentTime = sf.format(c.getTime()); if (tamp.compareTo(currentTime) > 0) { String hash = MD5Utils.code(identify);//生成MD5值 if (hash.equalsIgnoreCase(requestHash)){ //校驗成功 attributes.addFlashAttribute("m", "恭喜!現在,你可以登錄你的用戶名。"); return "redirect:/tourist"; }else { //驗證碼不正確,校驗失敗 System.out.println("2"); attributes.addFlashAttribute("message", "驗證碼輸入不正確"); return "redirect:/tourist/register"; } } else { // 超時 System.out.println("3"); attributes.addFlashAttribute("message", "驗證碼已過期"); return "redirect:/tourist/register"; } }
思路:判斷此時時間與上次存的驗證碼的生成時間之差是否大於五分鍾,若大於,則提示超時;若沒有大於,再將用戶輸入的驗證碼進行加密,接着判斷用戶輸入的驗證碼與最先保存的驗證碼是否一致(這里也可以通過驗證碼的解密,然后將解密后的驗證碼和用戶輸入的直接比對)
為了更方便地看出結果,我們再加個login界面,位置和register.html一樣
html代碼:
<!DOCTYPE html> <html lang="en" xmlns:th="http://www.w3.org/1999/xhtml"> <head > <meta charset="UTF-8"> <meta name="viewport" content="width=device-width,initial-scale=1.0"> <title>博客用戶登錄</title> <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/semantic-ui@2.4.2/dist/semantic.min.css"> </head> <body> <br><br><br> <div class="m-container-small m-padded-tb-massive" style="max-width: 30em !important;"> <div class="ui success message" th:unless="${#strings.isEmpty(m)}"> <i class="close icon"></i> <div class="header"> 你注冊成功! </div> <p th:text="${m}">現在,你可以登錄你的用戶名。</p> </div> <div class="ui container"> <div class="ui middle aligned center aligned grid"> <div class="column"> <h2 class="ui teal image header"> <div class="content"> 用戶登錄 </div> </h2> </div> </div> </div> </div> <script src="https://code.jquery.com/jquery-3.1.1.min.js" crossorigin="anonymous"></script> <script src="https://cdn.jsdelivr.net/npm/semantic-ui@2.4.2/dist/semantic.min.js"></script> //消息提示關閉初始化 $('.message .close') .on('click', function () { $(this) .closest('.message') .transition('fade'); }); </script> </body> </html>
現在又到了激動人心的測試環節,大家開始躁起來吧!
(具體演示忽略)
完善功能:用戶60秒才能重新發送郵箱,這樣可以避免某些壞心眼的孩子一直不斷地發送郵箱(哈哈雖然目的不只是這個),當然每次測試的時候我們也多了個60秒的等待時間
(欲知后事如何,請聽下回分解)
☞ 下篇文章:springboot中郵箱驗證按鈕實現60秒后可重新獲取(防止刷新)以及防重復發送
或者用你們的贊和鼓勵來加快我寫文章的步伐叭
參考:Spring Boot發送郵件詳解 https://www.iteye.com/blog/xieke90-2428892
轉載請注明出處