实现通过邮箱发送验证码找回密码功能需要具备一些Java基础知识、JavaWeb基础知识、MySQL基础知识以及理解简单的三层架构:Servlet层、Service层、Dao层。

编写过程中需要导入两个jar包,如有需要请三连私信博主免费领取。

一、先来看效果图

第一步:进入“找回密码”界面

java记住用户名和密码 java实现忘记密码方法_用户名

第二步:输入用户名与邮箱,如果与数据库不匹配则会输出提示信息,如果匹配则进入下一步。

java记住用户名和密码 java实现忘记密码方法_验证码_02

第三步:邮箱接收验证码

java记住用户名和密码 java实现忘记密码方法_java_03

邮箱中收到了java发送的邮件!

 第四步:填写验证码

java记住用户名和密码 java实现忘记密码方法_用户名_04

 第五步:设置新密码

java记住用户名和密码 java实现忘记密码方法_用户名_05

java记住用户名和密码 java实现忘记密码方法_用户名_06

 

java记住用户名和密码 java实现忘记密码方法_用户名_07

 

 输入两次一样的账号密码,点击完成,密码修改成功!

java记住用户名和密码 java实现忘记密码方法_java_08

 二、编程思路

需要3个前端jsp代码和3个servlet代码。

在第1个jsp代码中,创建两个表单,用于输入“用户名”和“邮箱”。用户输入完毕后,跳转至第1个servlet。

在第1个servlet中,首先获取用户输入的“用户名”和“邮箱”,然后通过“用户名”查询数据库,得到数据库中“用户名”对应的邮箱。因为有可能用户填写“用户名”和“邮箱”是不对应的,因此需要对用户填写的“邮箱”和通过数据库查询得到的“邮箱”进行判断,如果不匹配,则输出提示信息。如果匹配,则生成一个4位随机验证码。将4位验证码保存至session中(用于后续对用于输入的验证码进行验证),并将验证码以邮件的形式发送至用户邮箱。发送完毕后,跳转至第2个jsp(得到用户填写的“用户名”后也需要保存至session中,用于最后一步对密码进行修改)。

在第2个jsp代码中,创建一个表单,用于输入“验证码”。用户输入完毕后,跳转至第2个servlet。

在第2个servlet中,首先获取用户填写的“验证码”,然后获取session中的验证码,并将session中的验证码销毁(保证验证码的唯一性,这也是为什么邮件里说只能输入一次)。接着对用户填写的“验证码”和session中的验证码进行判断,如果不同则输出提示信息,返回到第一个页面。如果相同则跳转至第3个jsp。

在第3个jsp代码中,创建两个表单,用于输入两次“新密码”。这里需要对用户输入的“新密码”进行表单检验,使用户填写的“新密码”满足8-20字符且两次输入的“新密码”必须一致。如果用户填写完毕后,点击“完成”,则跳转至第3个servlet。

在第3个servlet中,获取session的“用户名”和用户填写的“新密码”。修改数据库中的数据,即可完成“设置新密码”。

三、上代码!

第1个jsp代码:

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="utf-8"/>
    <title>找回密码</title>
</head>

<body>
<div class="container" style="width: 400px;">
    <form action="${pageContext.request.contextPath}/repasswordServlet1" method="post">
        <div class="form-group">
            <label for="username">用户名:</label>
            <input type="text" name="username" id="username" class="form-control" placeholder="请输入您的用户名" required/>
        </div>
        <div class="form-group">
            <label for="email">邮箱:</label>
            <input type="email" name="email" id="email" class="form-control" placeholder="请输入您注册时填写的邮箱" required/>
        </div>

        <br><hr/>
        <div class="form-group" style="text-align: center;">
            <input class="btn btn btn-primary" type="submit" value="发送验证码">
            <input class="btn btn btn-primary" type="button" value="返回首页" onclick="javascript:window.location.href ='index.jsp'">
        </div>
    </form>
</div>
</body>
</html>

第1个servlet代码:

@Override
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        //1.设置编码、输出类
        request.setCharacterEncoding("utf-8");
        response.setContentType("text/html;charset=UTF-8");
        PrintWriter out = response.getWriter();
        //2.1获取用户的用户名
        String username = request.getParameter("username");
        //2.1.1把用户名保存在session中,方便后续判断
        request.getSession().setAttribute("username1",username);
        //2.2获取用户的邮箱
        String email = request.getParameter("email");
        //3.创建一个空的用户对象
        User user = null;
        //4.通过邮箱找到用户信息
        UserService service = new UserServiceImpl();
        user = service.findUserByUsername(username);
        //5.判断用户名与邮箱是否匹配
        if (user != null&&user.getEmail().equals(email)){
            //服务器通知浏览器不要缓存
            response.setHeader("pragma","no-cache");
            response.setHeader("cache-control","no-cache");
            response.setHeader("expires","0");

            String base = "0123456789ABCDEFGHIJKLMNOPQRSDUVWXYZabcdefghijklmnopqrsduvwxyz";
            int size = base.length();
            Random r = new Random();
            StringBuilder code = new StringBuilder();
            for(int i=1;i<=4;i++){
                //产生0到size-1的随机值
                int index = r.nextInt(size);
                //在base字符串中获取下标为index的字符
                char c = base.charAt(index);
                //将c放入到StringBuffer中去
                code.append(c);
            }
            //把验证码保存在session中,方便后续判断
            request.getSession().setAttribute("EmailCode",code.toString());

            //实例化一个发送邮件的对象
            SendEmail mySendMail = new SendEmail();
            //发送邮件
            mySendMail.sendMail(email, "您正在找回密码,验证码为:" + code.toString() +"\n只有一次输入机会,请正确输入!如非本人操作,请忽略。");
            //跳转页面
            out.println("<script>alert('验证码已发送至邮箱,请注意查收!');window.location.href='repassword2.jsp'</script>");
//            request.getRequestDispatcher("/repassword2.jsp").forward(request,response);
        }else {
            request.setAttribute("login_msg","用户名与邮箱不匹配,请重新输入!");
            request.getRequestDispatcher("/repassword1.jsp").forward(request,response);
        }

发送邮件的代码(需要2个jar包,不然报错)

package hssnw.util;

import javax.mail.MessagingException;
import javax.mail.NoSuchProviderException;
import javax.mail.Session;
import javax.mail.Transport;
import javax.mail.internet.InternetAddress;
import javax.mail.internet.MimeMessage;
import java.util.Date;
import java.util.Properties;

public class SendEmail {
    public static String sendEmailAccount = "发件人邮箱账号";
    public static String sendEmailPassword = "发件人邮箱的授权码";
    public static String sendEmailSMTPHost = "smtp.163.com";
    public static String receiveMailAccount = "无需填写空下即可";

    // 把发送邮件封装为函数,参数为收件人的邮箱账号和要发送的内容
    public void sendMail(String receiveMailAccount, String mailContent) {
        // 创建用于连接邮件服务器的参数配置
        Properties props = new Properties();
        // 设置使用SMTP协议
        props.setProperty("mail.transport.protocol", "smtp");
        // 设置发件人的SMTP服务器地址
        props.setProperty("mail.smtp.host", sendEmailSMTPHost);
        // 设置需要验证
        props.setProperty("mail.smtp.auth", "true");
        // 根据配置创建会话对象, 用于和邮件服务器交互
        Session session = Session.getInstance(props);
        // 设置debug模式,便于查看发送过程所产生的日志
        session.setDebug(true);
        try {
            // 创建一封邮件
            MimeMessage message = createMimeMessage(session, sendEmailAccount, receiveMailAccount, mailContent);
            // 根据 Session 获取邮件传输对象
            Transport transport = session.getTransport();
            transport.connect(sendEmailAccount, sendEmailPassword);
            // 发送邮件, 发到所有的收件地址, 通过message.getAllRecipients() 可以获取到在创建邮件对象时添加的所有收件人
            transport.sendMessage(message, message.getAllRecipients());
            // 关闭连接
            transport.close();
        } catch (NoSuchProviderException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (MessagingException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (Exception e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }

    public static MimeMessage createMimeMessage(Session session, String sendMail, String receiveMail,
                                                String mailContent) throws Exception {
        // 创建一封邮件
        MimeMessage message = new MimeMessage(session);

        // 设置发件人姓名和编码格式
        message.setFrom(new InternetAddress(sendMail, "发件人姓名", "UTF-8"));

        // 收件人
        message.setRecipient(MimeMessage.RecipientType.TO, new InternetAddress(receiveMail, "收件人", "UTF-8"));

        // 设置邮件主题
        message.setSubject("邮件主题", "UTF-8");

        // 设置邮件正文
        message.setContent(mailContent, "text/html;charset=UTF-8");

        // 设置发件时间
        message.setSentDate(new Date());

        // 保存设置
        message.saveChanges();

        return message;
    }
}

剩余代码很简单,大家改造一下即可完成。