zoukankan      html  css  js  c++  java
  • spring mvc下实现通过邮箱找回密码功能

    1功能分析

       通过spring mvc框架实现通过邮箱找回密码。

    2 实现分析

      主要是借助某个邮箱的pop3/smtp服务实现的邮件代发功能。

    3 源码分析

     3.1首先在用户表对应的javabean中加入两个字段outdate和validatecode用于验证数字签名。

         private String validatacode;
    	private Date outdate;
    	@Column(name = "validatacode", length = 50)
    	public String getValidatacode() {
    		return validatacode;
    	}
    
    	public void setValidatacode(String validatacode) {
    		this.validatacode = validatacode;
    	}
    	@Column(name = "outdate", length = 50)
    	public Date getOutdate() {
    		return outdate;
    	}
    
    	public void setOutdate(Date outdate) {
    		this.outdate = outdate;
    	}
    

      

     3.2发送邮件工具类

    package util;
    import java.security.GeneralSecurityException;
    import java.util.Properties;
    
    import javax.mail.Authenticator;
    import javax.mail.Message;
    import javax.mail.MessagingException;
    import javax.mail.PasswordAuthentication;
    import javax.mail.Session;
    import javax.mail.Transport;
    import javax.mail.internet.AddressException;
    import javax.mail.internet.InternetAddress;
    import javax.mail.internet.MimeMessage;
    
    import com.sun.mail.util.MailSSLSocketFactory;
     
    public class SendmailUtil {
         
        // 设置服务器
        private static String KEY_SMTP = "mail.smtp.host";
        private static String VALUE_SMTP = "smtp.163.com";//邮箱服务器地址
        // 服务器验证
        private static String KEY_PROPS = "mail.smtp.auth";
        private static boolean VALUE_PROPS = true;
        // 发件人用户名、密码
        private String SEND_USER = "填你用来做发送邮件的邮箱";
        private String SEND_UNAME = "发件人用户名";
        private String SEND_PWD = "*****";//这里是关键,是你开通了pop3/smtp服务以后获得的授权码
        // 建立会话
        private MimeMessage message;
        private Session s;
     
        /*
         * 初始化方法
         */
        public SendmailUtil() throws GeneralSecurityException {
            Properties props = System.getProperties();
            props.setProperty(KEY_SMTP, VALUE_SMTP);
            props.put(KEY_PROPS, "true");
            props.put("mail.smtp.auth", "true");
            MailSSLSocketFactory sf = new MailSSLSocketFactory();
            sf.setTrustAllHosts(true);
            props.put("mail.smtp.ssl.enable", "true");
            props.put("mail.smtp.ssl.socketFactory", sf);
            s =  Session.getDefaultInstance(props, new Authenticator(){
                  protected PasswordAuthentication getPasswordAuthentication() {
                      return new PasswordAuthentication(SEND_UNAME, SEND_PWD);
                  }});
            s.setDebug(true);
            message = new MimeMessage(s);
        }
     
        /**
         * 发送邮件
         * 
         * @param headName
         *            邮件头文件名
         * @param sendHtml
         *            邮件内容
         * @param receiveUser
         *            收件人地址
         */
        public void doSendHtmlEmail(String headName, String sendHtml,
                String receiveUser) {
            try {
                // 发件人
                InternetAddress from = new InternetAddress(SEND_USER);
                message.setFrom(from);
                // 收件人
                InternetAddress to = new InternetAddress(receiveUser);
                message.setRecipient(Message.RecipientType.TO, to);
                // 邮件标题
                message.setSubject(headName);
                String content = sendHtml.toString();
                // 邮件内容,也可以使纯文本"text/plain"
                message.setContent(content, "text/html;charset=GBK");
                message.saveChanges();
                Transport transport = s.getTransport("smtp");
                // smtp验证,就是你用来发邮件的邮箱用户名密码
                transport.connect(VALUE_SMTP, SEND_UNAME, SEND_PWD);
                // 发送
                transport.sendMessage(message, message.getAllRecipients());
                transport.close();
                System.out.println("send success!");
            } catch (AddressException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            } catch (MessagingException e) {
                e.printStackTrace();
            }
        }
     
       
    }
    

      3.3 spring mvc发送邮件

      首先要有前台页面,填写邮箱或用户名,示例图如下:

      

    jsp页面代码:

    <div class="container">
            <div class="col-md-12">
                <h1 class="margin-bottom-15">重置您的密码</h1>
                <form class="form-horizontal templatemo-forgot-password-form templatemo-container" role="form" action="javascript:findpwd();" method="post">    
                    <div class="form-group">
                      <div class="col-md-12">
                          请输入邮箱或用户名,点击确定。找回密码链接将发送至您的邮箱
                      </div>
                    </div>        
                    <div class="form-group">
                      <div class="col-md-12">
                        <input type="text" class="form-control" id="yhmoryx" placeholder="您的邮箱账号或用户名">                
                      </div>              
                    </div>
                    <div class="form-group">
                      <div class="col-md-12">
                        <input type="submit" value="确定" class="btn btn-danger">
                        <br><br>
                        <a href="#">无需重置密码,现在登录?</a> 
                        <!--<a href="login-2.html">用户名和注册邮箱已忘记,进行账号申诉?</a>-->
                      </div>
                    </div>
                  </form>
            </div>
        </div>

    后台接收请求代码:

     @RequestMapping(value = "/user/forgetpwd")
        @ResponseBody
        public Map forgetPass(HttpServletRequest request,@RequestParam("yhmoryx") String yhmoryx,Model model){
        	XtYh xtYh=xtYhService.getXtYhByYhmSjYx(yhmoryx);
           Map<String, String> map = new HashMap<String ,String >();
            String msg = "";
            if(yhmoryx.equals("")){              //用户名不存在
                msg = "请输入用户名或邮箱!";
              map.put("msg",msg);
                return map;
            }
            if(xtYh == null){              //用户不存在
                msg = "用户名不存在,你不会忘记用户名了吧?";
              map.put("msg",msg);
                return map;
            }
            try{
                String secretKey= UUID.randomUUID().toString();  //密钥
                Timestamp outDate = new Timestamp(System.currentTimeMillis()+30*60*1000);//30分钟后过期
                long date = outDate.getTime()/1000*1000;                  //忽略毫秒数
                xtYh.setValidatacode(secretKey);
                xtYh.setOutdate(outDate);
                xtYhService.updateXtYh(xtYh); //保存到数据库
                String key = xtYh.getYhm()+"$"+date+"$"+secretKey;
                String digitalSignature = Md5.MD5Encode(key);                 //数字签名
    
                String emailTitle = "密码找回";
                String path = request.getContextPath();
                String localstr=request.getLocalAddr();
                System.out.println(localstr);
                String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/";
                String resetPassHref =  basePath+"resetpassword/user/resetpassword?sid="+digitalSignature+"&yhm="+xtYh.getYhm();
                String emailContent = "请勿回复本邮件.点击下面的链接,重设密码<br/><a href="+resetPassHref +" target='_BLANK'>点击我重新设置密码</a>" +
                        "<br/>tips:本邮件超过30分钟,链接将会失效,需要重新申请'找回密码'"+"<br/>tips:本链接可能被邮箱拦截,如链接无效,请复制下列链接到您的浏览器中。<br/>"+
                		"链接开始:<span style='color:#F00; font-weight:bold'>"+resetPassHref+"<span>链接结束";
               //
          SendmailUtil.class.newInstance().doSendHtmlEmail(emailTitle,emailContent,xtYh.getYx());//调用工具类里面的发送发放
                msg = "操作成功,已经发送找回密码链接到您邮箱。请在30分钟内重置密码";
            }catch (Exception e){
                e.printStackTrace();
                msg="邮箱不存在?";
            }
            map.put("msg",msg);
            return map;
        }
    

      3.4 发送邮件以后用户点击链接(即上述的resetPassHref)再转到服务器上spring mvc的控制器部分,根据发回来的用户名和数字签名进行处理。

      确定以后会执行发送邮件功能,邮箱中接收到的信件如下:

      点击链接,会将请求发送到下面的控制器中进行处理:

    @RequestMapping(value = "/user/resetpassword",method = RequestMethod.GET)
        public String checkResetLink(@RequestParam("sid") String sid,@RequestParam("yhm")String yhm,Model model){
           	System.out.println(sid+yhm);
            String msg = "";
            if(sid.equals("") || yhm.equals("")){
                msg="链接不完整,请重新生成";
                model.addAttribute("msg",msg);
                return "findPwdError";
            }
            
            XtYh xtYh=xtYhService.getXtYhByYhm(yhm);
            if(xtYh == null){
                msg = "链接错误,无法找到匹配用户,请重新申请找回密码.";
                model.addAttribute("msg",msg) ;
                return "findPwdError";
            }
            Date outDate = xtYh.getOutdate();
            if(outDate.getTime() <= System.currentTimeMillis()){         //表示已经过期
                msg = "链接已经过期,请重新申请找回密码.";
                model.addAttribute("msg",msg) ;
                return "findPwdError";
            }
            String key = xtYh.getYhm()+"$"+outDate.getTime()/1000*1000+"$"+xtYh.getValidatacode();          //数字签名
            String digitalSignature = Md5.MD5Encode(key);
            System.out.println(key+"	"+digitalSignature);
            if(!digitalSignature.equals(sid)) {
                msg = "链接不正确,是否已经过期了?重新申请吧";
                model.addAttribute("msg",msg);
                return "findPwdError";
            }
           
            model.addAttribute("userName",yhm);
            return "resetpage";
        }
    

      4 再写一个update用户的操作。在上一步把用户的用户名(或id)传到前台页面,写一个input隐藏域。用户更改完以后点击确定,再把值传到后台,写入数据库。

      以下是点击链接以后的页面

      填入新密码,点击确定,跳转到登录界面

    【注:】参考至其他大神的博客。具体地址没记,去搜狗一下应该能找到

  • 相关阅读:
    对象方法Android之多媒体使用——MediaPlayer播放音频
    程序函数C语言中异常处理的两个函数
    退出窗口[置顶] 退出Activity的方法
    循环变量hdu 1799 循环多少次?
    网页剪辑有道云笔记、印象笔记(evernote)哪个更好?
    选项选择Windows XP系统安装MySQL5.5.28图解
    修改nullMyEclipse 设置文件的默认编码
    文件应用iOS开发用keychain替代UDID
    模块执行python模块介绍 struct 二进制数据结构
    数据库字符串AVP(AttributeValue Pair)
  • 原文地址:https://www.cnblogs.com/whutwxj/p/6044318.html
Copyright © 2011-2022 走看看