[记录] JavaMail邮箱验证用户注册

JavaMail——邮箱验证用户注册 : 有些代码没给,还好自己Servlet基础还是有的,所以还是整出来了

javamail发送邮件的简单实例 : 对邮件内容的组装和发送做了点封装,稍微做了点修改

JSP + Servlet 中文乱码问题解决

参考整合上面两篇,做了个Demo,中文乱码问题用第三篇解决

需要JavaMail的jar包

Demo结构

Demo结构

MailInfo.java 邮件相关信息

package zoey.model;

import java.util.Properties;

public class MailInfo {
  private String mailSmtpHost;
  private String mailSmtpPort = "25";
  private String fromAddress;
  private String toAddress;
  private String userName;
  private String password;
  private boolean validate = false;
  private String subject;
  private String content;
  private String[] attachFileNames;

  public Properties getProperties() {
    Properties p = new Properties();
    p.put("mail.smtp.host", this.mailSmtpHost);
    p.put("mail.smtp.port", this.mailSmtpPort);
    p.put("mail.smtp.auth", validate ? "true" : "false");
    return p;
  }

  // Getters & Setters
}

MyAuthenticator.java

package zoey.model;

import javax.mail.Authenticator;
import javax.mail.PasswordAuthentication;

public class MyAuthenticator extends Authenticator {
  private String userName;
  private String password;

  public MyAuthenticator() {
  }

  public MyAuthenticator(String userName, String password) {
    this.userName = userName;
    this.password = password;
  }

  @Override
  protected PasswordAuthentication getPasswordAuthentication() {
    return new PasswordAuthentication(userName, password);
  }
}

MailSender.java 邮件发送器,稍微做了点修改,使代码更少些

package zoey.model;

import java.util.Date;
import java.util.Properties;
import javax.mail.Address;
import javax.mail.BodyPart;
import javax.mail.Message;
import javax.mail.MessagingException;
import javax.mail.Multipart;
import javax.mail.Session;
import javax.mail.Transport;
import javax.mail.internet.InternetAddress;
import javax.mail.internet.MimeBodyPart;
import javax.mail.internet.MimeMessage;
import javax.mail.internet.MimeMultipart;

public class MailSender {
  public static boolean sendMail(MailInfo mailInfo, Boolean isMime) {
    MyAuthenticator authenticator = null;
    if (mailInfo.isValidate()) {
      authenticator = new MyAuthenticator(mailInfo.getUserName(), mailInfo.getPassword());
    }
    Properties pro = mailInfo.getProperties();
    Session session = Session.getDefaultInstance(pro, authenticator);
    try {
      Message message = new MimeMessage(session);
      Address from = new InternetAddress(mailInfo.getFromAddress());
      Address to = new InternetAddress(mailInfo.getToAddress());
      message.setFrom(from);
      message.setRecipient(Message.RecipientType.TO, to);
      message.setSubject(mailInfo.getSubject());
      message.setSentDate(new Date());
      if (!isMime) {
        message.setText(mailInfo.getContent());
      } else {
        BodyPart html = new MimeBodyPart();
        html.setContent(mailInfo.getContent(), "text/html; charset=utf-8");
        Multipart mainPart = new MimeMultipart();
        mainPart.addBodyPart(html);
        message.setContent(mainPart);
      }
      Transport.send(message);
      return true;
    } catch (MessagingException ex) {
      ex.printStackTrace();
    }
    return false;
  }
}

先给出:web.xml

<?xml version="1.0" encoding="UTF-8"?>
<web-app id="WebApp_ID" version="2.4"
  xmlns="http://java.sun.com/xml/ns/j2ee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd">
  <servlet>
    <servlet-name>RegisterServlet</servlet-name>
    <servlet-class>zoey.register.RegisterServlet</servlet-class>
  </servlet>

  <servlet-mapping>
    <servlet-name>RegisterServlet</servlet-name>
    <url-pattern>/RegisterServlet.do</url-pattern>
  </servlet-mapping>

  <servlet>
    <servlet-name>MailBackServlet</servlet-name>
    <servlet-class>zoey.register.MailBackServlet</servlet-class>
  </servlet>

  <servlet-mapping>
    <servlet-name>MailBackServlet</servlet-name>
    <url-pattern>/MailBackServlet.do</url-pattern>
  </servlet-mapping>

  <!-- 定义字符转换过滤器 -->
  <filter>
    <filter-name>SetCharacterEncoding</filter-name>
    <filter-class>zoey.util.SetCharacterEncoding</filter-class>
    <!-- 设置参数名称及参数值 -->
    <init-param>
      <param-name>encoding</param-name>
      <param-value>UTF-8</param-value>
    </init-param>
  </filter>
  <!-- 映射定义的Filter,设置对所有的请求进行过滤 -->
  <filter-mapping>
    <filter-name>SetCharacterEncoding</filter-name>
    <url-pattern>/*</url-pattern>
  </filter-mapping>
</web-app>

注册页面:index.jsp

<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<title>用户注册</title>
</head>
<body>
<h1>用户注册</h1><hr/><br/>
<form action="RegisterServlet.do" method="post">
    邮箱: <input type="text" name="email" /><br/><br/>
    昵称: <input type="text" name="userName" /><br/><br/>
    <input type="submit" value="确认注册" />
</form>
</body>
</html>

点击注册后:RegisterServlet.java

package zoey.register;

import java.io.IOException;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

import zoey.model.MailInfo;
import zoey.model.MailSender;

public class RegisterServlet extends HttpServlet {
  @Override
  protected void doGet(HttpServletRequest request,
    HttpServletResponse response) throws ServletException, IOException {
    String registerName = request.getParameter("userName");
    String registerMail = request.getParameter("email");
    String registerId = "" + Math.random() * Math.random();
    String url = "http://localhost:8080/EmailRegister/MailBackServlet.do?registerId=" + registerId;
    HttpSession httpSession = request.getSession();
    httpSession.setAttribute(registerId, registerName);
    httpSession.setMaxInactiveInterval(600);

    String content = registerName + "(" + registerMail + "),您好<br/>感谢您注册XXXXX!<br/>"
    + "<b>验证您的邮箱地址注册</b><br/>请点击下面的链接来确认您的注册<br/>"
    + "<a href='" + url + "'>确认!请点击这里验证此邮件</a><br/>"
    + "如果您不能点击上述标签为“确认!”的链接,您还可以通过复制(或输入)下面的URL到地址栏中来验证您的邮件地址。"
    + "<a href='" + url + "'>" + url + "</a><br/>"
    + "如果您认为这是垃圾邮件,请忽略此邮件。";

    MailInfo mailInfo = new MailInfo();
    mailInfo.setMailSmtpHost("yourmail's smtp host"); // 根据实际修改
    mailInfo.setFromAddress("yourmail@whatever.com"); // 根据实际修改
    mailInfo.setToAddress(registerMail);
    mailInfo.setUserName("yourmail@whatever.com"); // 根据实际修改
    mailInfo.setPassword("password"); // 根据实际修改
    mailInfo.setValidate(true);      // 根据实际修改
    mailInfo.setSubject("邮件主题"); // 根据实际修改
    mailInfo.setContent(content);

    MailSender.sendMail(mailInfo, true); // true发送HTML格式邮件,false发送纯文本
    request.setAttribute("userName", registerName);
    request.setAttribute("email", registerMail);
    request.getRequestDispatcher("/sendMailSuccess.jsp").forward(request, response);
  }

  @Override
  protected void doPost(HttpServletRequest request,
    HttpServletResponse response) throws ServletException, IOException {
      doGet(request, response);
  }
}

发送成功后转到页面:sendMailSuccess.jsp

<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<title>帐号确认</title>
</head>
<body>
<h1>帐号确认</h1>
<%
    String userName = request.getParameter("userName");
    String email = request.getParameter("email");
    String sub = email.substring(email.indexOf('@') + 1);
    if (sub.equals("gmail")) { sub = "google"; } // 特殊处理
    String url = "http://mail." + sub;
%>
${userName}您的邮箱<a target="_blank" href="<%=url %>">${email}</a>还没确认,您必须尽快进行帐户激活(登录该邮箱,并按照帐号激活通知的指示操作)。否则您的帐号将很快被删除!<br/>
您还没有收到激活信?点击<a href="RegisterServlet.do?userName=<%=userName%>&email=<%=email%>">这里</a>重新发送激活邮件。
</body>
</html>

点击验证邮箱链接后:MailBackServlet.java

package zoey.register;

import java.io.IOException;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

public class MailBackServlet extends HttpServlet {

  @Override
  public void doGet(HttpServletRequest request, HttpServletResponse response)
  throws ServletException, IOException {
    String registerId = request.getParameter("registerId");
    if (registerId == null) {
      request.getRequestDispatcher("/index.jsp").forward(request, response);
      return;
    }

    String registerName = (String) request.getSession().getAttribute(registerId);

    if (registerName == null || registerName.equals("")) {
      request.getRequestDispatcher("/index.jsp").forward(request, response);
      return;
    }

    request.setAttribute("registerName", registerName);
    request.getRequestDispatcher("/registerSuccess.jsp").forward(request, response);
  }

  @Override
  public void doPost(HttpServletRequest request, HttpServletResponse response)
  throws ServletException, IOException {
    doGet(request, response);
  }
}

注册成功:registerSuccess.jsp

<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<title>注册成功</title>
</head>
<body>
    ${registerName} 恭喜您,从现在起,您就是本站的一员了。
</body>
</html>

存在的问题:

  1. 刷新重复提交,另外做整理
  2. 通过session来判断不合理,得在同一个浏览器中才能显示注册成功(session作用域和生命周期内),这里只是作为演示用

可以在数据库中设置一个是否激活字段,注册时为未激活,然后在验证后设置为激活

还是比较容易集成到系统中的