使用邮箱找回密码-发验证码到邮箱
大致思路
最近在写一个系统,过程中有忘记密码?这步操作。这里介绍我使用的邮箱发送验证码进行修改。
使用的是IntelliJ IDEA 2023.3.2
maven-3.9.6
apache-tomcat-8.5.98
MySQL 8.0.36.0
jdk1.8
主要思路如下:
-
找回密码的jsp,输入电子邮箱,点击发送。
-
再写个验证邮箱的servlet。根据输入的电子邮箱先在数据库内查找是否存在这个邮箱。比如我这个系统是用户管理员,那么就要再写个dao类来查询数据库里是否存在这个邮箱。那就是在users表和admins表内分别查找。
-
如果存在这个邮箱,就可以调用发送邮件的方法进行邮件发送,否则就返回邮箱不存在。
-
发送邮件的类就放在untils包里面,里面主要是邮箱的接口配置,邮件内容,标题,发件人邮箱以及发件邮箱的授权码。
-
邮件发送成功则显示发送成功,否则发送失败。
找回密码jsp
<body>
<div class="password-forget-container">
<h1>找回密码</h1>
<form action="/SendEmailServlet" method="post" onsubmit="return validateForm()">
<div class="form-row">
<label for="email" class="label">电子邮箱:</label>
<input type="text" id="email" name="email" class="input">
</div>
<br>
<div class="form-group" style="text-align: center;">
<input class="btn btn btn-primary" type="button" value="返回登录" onclick="javascript:window.location.href ='login.jsp'">
<input class="btn btn btn-primary" type="submit" value="发送铭牌码" >
</div>
<div id="result"></div>
</form>
</div>
</body>
除了填写表单信息,还需要对邮箱进行验证,如邮箱格式以及邮箱是否填写。
function validateForm() {
var email = document.getElementById("email").value;
var emailRegex = /^[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\.[A-Za-z]{2,}(?:\.[A-Za-z]{2,})?$/;
if (email === "") {
alert("邮箱不能为空!");
return false;
} else if (!emailRegex.test(email)) {
alert("邮箱格式不正确!");
return false;
}
return true;// 返回true表示表单提交
}
验证的servlet
验证邮箱否存在于自己的数据库中
@WebServlet(name = "SendEmailServlet", value = "/SendEmailServlet")
public class SendEmailServlet extends HttpServlet {
@Override
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
String email = request.getParameter("email");
boolean emailExistsInUsersTable = DatabaseHelper.checkEmailExistsInUsersTable(email);
boolean emailExistsInAdminsTable = DatabaseHelper.checkEmailExistsInAdminsTable(email);
if (emailExistsInUsersTable || emailExistsInAdminsTable) {
boolean emailSent = EmailSender.sendEmail(email); // 发送邮件
if (emailSent) {
// 邮件发送成功,重定向到成功页面
response.sendRedirect("jsp/fPsuccess.jsp");
} else {
// 邮件发送失败跳转到失败页面
response.sendRedirect("jsp/fPfailure.jsp");
}
} else {
// 邮箱不存在跳转到失败页面
response.sendRedirect("jsp/emailNotExist.jsp");
}
}
}
关于邮箱是否存在数据库中
这DatabaseHelper类放在dao包
因为我的系统是用户/管理员,两种类型,我的数据库中也是对应的users表和admins表。所以需要两个表都使用SQL语句进行数据库查找。查找完就关闭数据库。(数据库的配置你肯定在untils里面写好了,因为注册时候就会用到数据库的连接)
public class DatabaseHelper {
// 在用户表中查找是否存在该邮箱
public static boolean checkEmailExistsInUsersTable(String email) {
String sql = "SELECT COUNT(*) FROM users WHERE email = ?";
Connection connection = null;
PreparedStatement statement = null;
ResultSet resultSet = null;
try {
connection = DBUtils.getConnection();
statement = connection.prepareStatement(sql);
statement.setString(1, email);
resultSet = statement.executeQuery();
if (resultSet.next()) {
int count = resultSet.getInt(1);
return count > 0;
}
} catch (SQLException e) {
e.printStackTrace();
} finally {
try {
if (resultSet != null) {
resultSet.close();
}
if (statement != null) {
statement.close();
}
} catch (SQLException e) {
e.printStackTrace();
} finally {
DBUtils.closeConnection();
}
}
return false;
}
// 在管理员表中查找是否存在该邮箱
public static boolean checkEmailExistsInAdminsTable(String email) {
String sql = "SELECT COUNT(*) FROM admins WHERE email = ?";
Connection connection = null;
PreparedStatement statement = null;
ResultSet resultSet = null;
try {
connection = DBUtils.getConnection();
statement = connection.prepareStatement(sql);
statement.setString(1, email);
resultSet = statement.executeQuery();
if (resultSet.next()) {
int count = resultSet.getInt(1);
return count > 0;
}
} catch (SQLException e) {
e.printStackTrace();
} finally {
try {
if (resultSet != null) {
resultSet.close();
}
if (statement != null) {
statement.close();
}
} catch (SQLException e) {
e.printStackTrace();
} finally {
DBUtils.closeConnection();
}
}
return false;
}
}
进行邮箱授权码的获取
发送邮件之前肯定要先前往邮箱进行设置,下面列出常见的QQ邮箱、163邮箱、126邮箱的授权码开启。这样就可以发送邮件。
授权码开启:
qq:
在这一栏进行开启,我现在是开启后的状态。(按照邮箱的引导教程开启就可以)
163:
在这里进行开启,这两个都要开启
126:
也是两个都开启
授权码开启后:
163:
qq:
126:
发送邮件类
这个发送邮件类我写到了untils里面
包括6位随机验证码、邮件主题、内容、发件人邮箱、邮件服务器端口号等等
public class EmailSender {
private static final String PROTOCOL = "smtp";//协议
private static final String SMTP_HOST = "smtp.163.com"; // 邮件服务器地址(我这里使用的是163邮箱)
private static final String SMTP_PORT = "465"; // 邮件服务器端口号
private static final String SENDER_EMAIL = "xxxxx@163.com"; // 你设置的发件人的邮箱地址
private static final String SENDER_PASSWORD = "xxxxxxx"; // 你设置的发件人的邮箱授权码
public static boolean sendEmail(String recipientEmail) {
String subject = "【xxxxx系统】找回密码";
String verificationCode = generateVerificationCode();
String body = "您的铭牌码为: " + verificationCode;
Properties props = new Properties();
props.put("mail.smtp.host", SMTP_HOST);
props.put("mail.smtp.port", SMTP_PORT);
props.put("mail.smtp.protocol", PROTOCOL);
props.put("mail.smtp.ssl.enable", "true");
props.put("mail.smtp.ssl.socketFactory", "javax.net.ssl.SSLSocketFactory");
props.put("mail.smtp.auth", "true");
props.put("mail.smtp.starttls.enable", "true");
Session session = Session.getInstance(props, new Authenticator() {
@Override
protected PasswordAuthentication getPasswordAuthentication() {
return new PasswordAuthentication(SENDER_EMAIL, SENDER_PASSWORD);
}
});
try {
Message message = new MimeMessage(session);
message.setFrom(new InternetAddress(SENDER_EMAIL));
message.setRecipients(Message.RecipientType.TO, InternetAddress.parse(recipientEmail));
message.setSubject(subject);
message.setText(body);
Transport.send(message);
return true;
} catch (MessagingException e) {
e.printStackTrace();
return false;
}
}
private static String generateVerificationCode() {
Random random = new Random();
int code = 100000 + random.nextInt(900000); // 生成6位随机数字验证码
return String.valueOf(code);
}
}
导入的jar包
要成功发送邮件,必须导入以下两个jar包
手动导入,放在项目的lib目录下。
或者在maven依赖里添加,
<dependency>
<groupId>com.sun.mail</groupId>
<artifactId>javax.mail</artifactId>
<version>1.6.2</version>
</dependency>
<dependency>
<groupId>javax.activation</groupId>
<artifactId>activation</artifactId>
<version>1.1.1</version>
</dependency>
程序界面
找回密码界面:
邮箱格式不正确或者邮箱不填写时候会弹出提示框
邮箱不存在时候(输入的邮箱不是注册过的邮箱,所以数据库没有这个邮箱)
邮箱存在,并且邮件发送成功
邮件发送失败
然后邮件发送成功时候,收件人邮箱收到的是
然后就可以在接下来的重置密码页面输入邮箱获取的铭牌码,然后进行新密码操作了。
结语
在邮件发送过程中,出现了很多次问题,bug也碰到了很多,但是一定要细心,不要着急,出问题可以在调试里面查看问题,或者打印输入日志查看。
出现什么问题咨询我。