找回密码(一)【实际项目】
(一)第一个jsp页面
页面效果
代码
1 <div class="wjmm"><a href="/forgot_password.jspx" class="fg_pw" >忘记密码</a></div></div>
(二)跳转到controller方法
1 @RequestMapping( value = "/forgot_password.jspx" ) 2 public String forgotPasswordForm( HttpServletRequest request, HttpServletResponse response, 3 org.springframework.ui.Model modelMap ) { 4 Site site = Context.getCurrentSite( request ); 5 Map<String, Object> data = modelMap.asMap(); 6 ForeContext.setData( data, request ); 7 return site.getTemplate( FORGOT_PASSWORD_TEMPLATE ); 8 } 9 10 /** 11 * 忘记密码模板 12 */ 13 public static final String FORGOT_PASSWORD_TEMPLATE = "sys_member_forgot_password.html";
(三)找回密码页面
页面效果
1 [#escape x as (x)!?html] 2 <!doctype html> 3 <html lang="zh-CN"> 4 <head> 5 <meta charset="utf-8"/> 6 <meta http-equiv="X-UA-Compatible" content="IE=Edge,chrome=1"> 7 <title>找回密码_${site.fullNameOrName}${global.customs['poweredby']}</title> 8 <meta name="keywords" content="${node.keywords}"/> 9 <meta name="description" content="${node.description}"/> 10 <link href="_files/css/common.css" rel="stylesheet"/> 11 <link href="_files/css/content.css" rel="stylesheet"/> 12 <link href="_files/css/global.css" rel="stylesheet"/> 13 <link href="_files/css/style.css" rel="stylesheet"/> 14 <style type="text/css"> 15 .login-wrap{ 16 border-top: solid 0px #9d1e28; 17 } 18 </style> 19 [#include 'inc_js.html'/] 20 </head> 21 <body> 22 <!-- target="_blank" --> 23 <form id="validForm" action="${ctx}/forgot_password.jspx" method="post"> 24 <input type="hidden" name="status_0" value="申请修改密码成功,请注意查收邮件!"> 25 <input type="hidden" name="timeout" value="-1"> 26 <!--登陆--> 27 <div class="login-wrap"> 28 <div id="login"> 29 <div class="lg_tl">找回密码</div> 30 <div class="lg_con clearfix"> 31 <div class="lgc_inr"> 32 <div class="labelbox"><span>用户名:</span><input type="text" id="username" name="username" class="text required" value="${username!}"placeholder="请输入用户名"/></div> 33 <div class="labelbox"><span>邮 箱:</span><input type="text" id="email" name="email" class="text" value=""placeholder="请输入邮箱"/></div> 34 <div class="labelbox"><span>验证码:</span> 35 <div class="input"> 36 <input type="text" id="captcha" name="captcha" class="text" 37 style="width: 94px;" data-rule-required="true" 38 data-rule-remote='{"url":"${ctx}/captcha.servlet","type":"post"}' 39 data-msg-remote="验证码错误" /> <img src="${ctx}/captcha.servlet" 40 onclick="this.src='${ctx}/captcha.servlet?d='+new Date()*1;$('#captcha').focus();" 41 style="cursor: pointer; border: 1px solid #ccc; margin: 0; vertical-align: top;" 42 title="点击重新获取验证码" /> 43 </div> 44 <label for="captcha" generated="true" class="hide error"></label> 45 46 </div> 47 <div class="lgc_ot">已有账号? 点击<a href="${ctx}/login.jspx">登陆</a></div> 48 </div> 49 </div> 50 <div class="lg_btn"> 51 <a id="toLogin">提交</a> 52 </div> 53 </div> 54 </div> 55 </form> 56 <script type="text/javascript"> 57 $(function(){ 58 $("#validForm").validate({ 59 rules: { 60 username: "required", 61 email:{ 62 required:true, 63 email:true 64 } 65 }, 66 messages: { 67 username: "用户名不能为空", 68 email:{ 69 required:"邮箱不能为空", 70 email:"邮箱格式不正确" 71 } 72 }, 73 errorPlacement: function (error, element) { 74 error.insertAfter(element); 75 }, 76 submitHandler:function(form){ 77 form.submit(); 78 } 79 }); 80 81 document.onkeydown = function(e){ 82 var ev = document.all ? window.event : e; 83 if(ev.keyCode==13) { 84 $('#validForm').submit(); 85 } 86 } 87 88 $("#toLogin").click(function(){ 89 $('#validForm').submit(); 90 }) 91 }) 92 </script> 93 </body> 94 </html> 95 [/#escape]
(四)controller方法
思路:
该方法首先验证用户名和邮箱,如果不存在返回;
然后发邮件到邮箱
验证不通过页面
方法主代码
1 //找回密码方法 2 3 @RequestMapping( value = "/forgot_password.jspx", method = RequestMethod.POST ) 4 public String forgotPasswordSubmit( String username, String email, String captcha, HttpServletRequest request, 5 HttpServletResponse response, org.springframework.ui.Model modelMap ) { 6 Response resp = new Response( request, response, modelMap ); 7 String result = validateForgotPasswordSubmit( request, resp, username, email, captcha ); 8 if( resp.hasErrors() ) { 9 return result; 10 } 11 12 Site site = Context.getCurrentSite( request ); 13 User forgotUser = userService.findByUsername( username ); 14 GlobalRegister reg = site.getGlobal().getRegister(); 15 GlobalMail mail = site.getGlobal().getMail(); 16 String subject = reg.getPasswordEmailSubject(); 17 String text = reg.getPasswordEmailText(); 18 userService.sendPasswordEmail( site, forgotUser, mail, subject, text ); 19 resp.addData( "username", username ); 20 resp.addData( "email", email ); 21 return resp.post(); 22 }
方法第一步的验证码代码
1 private String validateForgotPasswordSubmit( HttpServletRequest request, Response resp, String username, String email, 2 String captcha ) { 3 List<String> messages = resp.getMessages(); 4 if( !Captchas.isValid( captchaService, request, captcha ) ) { 5 return resp.post( 100, "error.captcha" ); 6 } 7 if( !Validations.notEmpty( username, messages, "username" ) ) { 8 return resp.post( 401 ); 9 } 10 if( !Validations.notEmpty( email, messages, "email" ) ) { 11 return resp.post( 402 ); 12 } 13 14 User forgotUser = userService.findByUsername( username ); 15 if( !Validations.exist( forgotUser ) ) { 16 return resp.post( 501, "forgotPassword.usernameNotExist", new String[] { username } ); 17 } 18 if( !StringUtils.equals( forgotUser.getEmail(), email ) ) { 19 return resp.post( 502, "forgotPassword.emailNotMatch" ); 20 } 21 return null; 22 }
方法中的发送邮件方法
邮件图片为:
1 @Transactional 2 public void sendPasswordEmail(Site site, User user, GlobalMail mail, 3 String subject, String text) { 4 UserDetail detail = user.getDetail(); 5 String key = StringUtils.remove(UUID.randomUUID().toString(), '-'); 6 user.setValidationKey(key); 7 user.setValidationType(Constants.RETRIEVE_PASSWORD_TYPE); //RETRIEVE_PASSWORD_TYPE=retrieve_password
8 detail.setValidationDate(new Date()); 9 detail.setValidationValue(null); 10 11 String url = site.getProtocol() + ":" + site.getUrlFull() 12 + Constants.RETRIEVE_PASSWORD_URL + key; 13 String email = user.getEmail(); 14 String username = user.getUsername(); 15 String sitename = site.getFullNameOrName(); 16 subject = GlobalRegister.replacePasswordEmail(subject, username, 17 sitename, url); 18 text = GlobalRegister.replacePasswordEmail(text, username, sitename, 19 url); 20 mail.sendMail(new String[] { email }, subject, text); 21 }
发送邮件工具类省略——放到后面随笔中进行
(五)点击邮件链接通过controller方法找到重置密码页面
controller方法
1 @RequestMapping( value = "/retrieve_password.jspx" ) 2 public String retrievePasswordForm( String key, HttpServletRequest request, HttpServletResponse response, 3 org.springframework.ui.Model modelMap ) { 4 Response resp = new Response( request, response, modelMap ); 5 List<String> messages = resp.getMessages(); 6 if( !Validations.notEmpty( key, messages, "key" ) ) { 7 return resp.badRequest(); 8 } 9 10 Site site = Context.getCurrentSite( request ); 11 User retrieveUser = userService.findByValidation( Constants.RETRIEVE_PASSWORD_TYPE, key ); 12 modelMap.addAttribute( "retrieveUser", retrieveUser ); 13 modelMap.addAttribute( "key", key ); 14 Map<String, Object> data = modelMap.asMap(); 15 ForeContext.setData( data, request ); 16 return site.getTemplate( RETRIEVE_PASSWORD_TEMPLATE ); //RETRIEVE_PASSWORD_TEMPLATE = "sys_member_retrieve_password.html"
17 }
重置密码页面
重置密码页面代码
1 [#escape x as (x)!?html] 2 <!doctype html> 3 <html lang="zh-CN"> 4 <head> 5 <meta charset="utf-8"/> 6 <meta http-equiv="X-UA-Compatible" content="IE=Edge,chrome=1"> 7 <title>重置密码_${site.fullNameOrName}${global.customs['poweredby']}</title> 8 <meta name="keywords" content="${node.keywords}"/> 9 <meta name="description" content="${node.description}"/> 10 <link href="_files/css/common.css" rel="stylesheet"/> 11 <link href="_files/css/content.css" rel="stylesheet"/> 12 <link href="_files/css/global.css" rel="stylesheet"/> 13 <link href="_files/css/style.css" rel="stylesheet"/> 14 <style type="text/css"> 15 .login-wrap{ 16 border-top: solid 0px #9d1e28; 17 } 18 </style> 19 [#include 'inc_js.html'/] 20 </head> 21 <body> 22 23 <!-- target="_blank" --> 24 <form id="validForm" action="${ctx}/retrieve_password.jspx" method="post"> 25 <input type="hidden" name="status_0" value="密码修改成功,请用新密码登录!"> 26 <input type="hidden" name="key" value="${Param.key!}"> 27 <!--登陆--> 28 <div class="login-wrap"> 29 <div id="login"> 30 <div class="lg_tl">重置密码</div> 31 <div class="lg_con clearfix"> 32 <div class="lgc_inr"> 33 <div class="labelbox"><span>新密码 :</span><input type="password" id="password" name="password" class="text required" placeholder="请输入密码" style="width:380px;"/></div> 34 <div class="labelbox"><span>确认密码:</span><input type="password" id="passwordAgain" name="passwordAgain" class="text" equalTo="#password" placeholder="请再次输入密码" style="width:380px;"/></div> 35 36 <div class="lgc_ot">已有账号,点击<a href="${ctx}/login.jspx">现在登录</a></div> 37 </div> 38 </div> 39 <div class="lg_btn"> 40 <a id="toLogin">提交</a> 41 </div> 42 </div> 43 </div> 44 </form> 45 <script type="text/javascript"> 46 $(function(){ 47 $("#validForm").validate({ 48 rules: { 49 password: { 50 required: true, 51 minlength: 6, 52 maxlength: 20 53 } 54 }, 55 messages: { 56 password:{ 57 required: "请输入密码", 58 minlength: "密码长度不能小于6个字符", 59 maxlength: "密码长度不能超过20个字符" 60 } 61 }, 62 errorPlacement: function (error, element) { 63 error.insertAfter(element); 64 }, 65 submitHandler:function(form){ 66 var password=$("#password"), 67 confirm_password=$("#passwordAgain"); 68 69 if(confirm_password.val()!==password.val()){ 70 confirm_password.closest(".labelbox").append('<label for="passwordAgain" class="error">两次输入密码不一致</label>') 71 return; 72 } 73 form.submit(); 74 } 75 }); 76 77 document.onkeydown = function(e){ 78 var ev = document.all ? window.event : e; 79 if(ev.keyCode==13) { 80 $('#validForm').submit(); 81 } 82 } 83 84 $("#toLogin").click(function(){ 85 $('#validForm').submit(); 86 }) 87 }) 88 </script> 89 </body> 90 </html> 91 [/#escape]