JavaMail学习笔记(七)、帐号激活与忘记密码 实例(zhuan)

时间:2022-05-09 08:19:40

一、帐户激活

 

在很多时候,在某些网站注册一个用户之后,网站会给这个用户注册时填写的email地址发送一封帐户激活邮件,这封邮件的内容就是一个激活帐户的链接和一段简短的文字描述,如果用户没有去邮箱将帐户激活,可能在使用网站的某些功能时就会受到限制,比如不能发贴、下载资料、评论等限制。这么做的原因应该是为了保证帐户的安全性和邮箱的有效性,以后网站如果有什么活动、资讯或系统安全通知等,可以在第一时间通知到用户。比如我在奇艺视频网站注册一个帐号之后,它就会往我注册时填写的邮箱中发一封帐户激活的邮件,邮件中有一个激活的链接,点击它就可以将你的帐户激活。如下图所示:

JavaMail学习笔记(七)、帐号激活与忘记密码 实例(zhuan)

这个功能是怎么做到的呢,其实实现也是很简单的,说白了就是一个Update操作。

实现思路:当一个用户注册成功之后,系统向用户注册时提供的email地址发送一封邮件,邮件的内容是一个激活帐户的链接和一段简短的文字描述,这个链接的功能就是将这个帐户的状态修改成激活状态。这个功能的重点在于如何生成这个激活帐户的链接。直接可以联想到的方法就是建一个Servlet,Servlet接收一个用户名参数,Servlet拿到用户名参数之后,到数据库把这条记录load出来,做一次update操作即可。但是这样做会有风险,比如有人想在你的网站上搞破坏,注册时他填的email地址就是乱填的,这个Email地址可能根本就收不到邮件(但符合email格式),注册完成之后,然后在浏览器地址栏输入网站之前发送的帐户激活链接,并加上新注册的用户名参数,这样一来就跳过了去邮箱激活的步聚,时间久了,库中可能会留下许多无效的email地址和帐户。为了避免这个问题,解决方案是在用户注册成功之后,在发送激活帐户的链接中加一个随机码,这个随机码是将用户名和一个随机数用md5加密后的一串16进制字符串,每次用户在激活帐户的时候,都验证这个随机码是否和注册时发送的一致,这样就可以避免人为的修改激活链接达到帐户激活的功能。

二、忘记密码

 

当你在某网站注册一个帐户之后,发现这个帐户很久没用了,密码也忘记了,如果还记得之前注册时填写的Email,那就可以向你的email中发一个重设密码的链接,就可以重新设置你的密码。大部份网站一般都提供了根据Email找回密码的功能。实现此功能的思路:在登录界面添加一个“忘记密码“的链接,用户点击进去之后,输入用户名或Email,系统根据用户名或Email找出用户信息,并生成一个重新设置密码的链接发送到用户的邮箱中(生成链接的方式和生成帐户激活链接的方式一样),用户在邮箱中点击重设密码的链接,根据提示进入密码重设页面,重新输入新的密码即可。

功能实现步聚(帐号激活):

1、用户注册页面

  1. <form action="${pageContext.request.contextPath}/register" method="post">
  2. 用户名:<input type="text" name="userName" value="${param.userName}"><span class="error">${errors.userName}</span><br/>
  3. 密码:<input type="password" name="password" ><span class="error">${errors.password}</span><br/>
  4. 确认密码:<input type="password" name="password2"><span class="error">${errors.password2}</span><br/>
  5. email:<input type="text" name="email" value="${param.email}"><span class="error">${errors.email}</span><br/>
  6. <input type="submit" value="注册">
  7. </form>

2、处理注册请求的Servlet(RegisterServlet)

  1. package org.study.accountactivate.web.servlet;
  2. import java.io.IOException;
  3. import java.util.HashMap;
  4. import java.util.Map;
  5. import javax.servlet.ServletException;
  6. import javax.servlet.http.HttpServlet;
  7. import javax.servlet.http.HttpServletRequest;
  8. import javax.servlet.http.HttpServletResponse;
  9. import org.study.accountactivate.dao.UserDao;
  10. import org.study.accountactivate.dao.impl.UserDaoImpl;
  11. import org.study.accountactivate.domail.User;
  12. import org.study.accountactivate.util.EmailUtils;
  13. /**
  14. * 用户注册
  15. */
  16. public class RegisterServlet extends HttpServlet {
  17. private static final long serialVersionUID = 1L;
  18. private UserDao userDao = UserDaoImpl.getInstance();
  19. protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
  20. doPost(request, response);
  21. }
  22. protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
  23. String userName = request.getParameter("userName");
  24. String password = request.getParameter("password");
  25. String password2 = request.getParameter("password2");
  26. String email = request.getParameter("email");
  27. Map<String, String> errors = new HashMap<String,String>();
  28. if (userName == null || "".equals(userName)) {
  29. errors.put("userName", "用户名不能为空!");
  30. } else if (userName != null && userDao.findUserByName(userName) != null) {
  31. errors.put("userName", "该用户已注册!");
  32. }
  33. if (password == null || "".equals(password)) {
  34. errors.put("password","密码不能为空!");
  35. } else if (password != null && password.length() < 3) {
  36. errors.put("password","密码长度不能低于3位!");
  37. }
  38. if (password2 == null || "".equals(password2)) {
  39. errors.put("password2", "确认密码不能为空!");
  40. } else if (password2 != null && !password2.equals(password)) {
  41. errors.put("password2", "两次输入的密码不一致!");
  42. }
  43. if (email == null || "".equals(email)) {
  44. errors.put("email", "email不能为空!");
  45. } else if (email != null && !email.matches("[0-9a-zA-Z_-]+@[0-9a-zA-Z_-]+\\.[0-9a-zA-Z_-]+(\\.[0-9a-zA-Z_-])*")) {
  46. errors.put("email", "email格式不正确!");
  47. }
  48. if (!errors.isEmpty()) {
  49. request.setAttribute("errors", errors);
  50. request.getRequestDispatcher("/registerUI").forward(request, response);
  51. return;
  52. }
  53. User user = new User();
  54. user.setUserName(userName);
  55. user.setPassword(password);
  56. user.setEmail(email);
  57. user.setActivated(false);
  58. userDao.addUser(user);
  59. // 注册成功后,发送帐户激活链接
  60. EmailUtils.sendAccountActivateEmail(user);
  61. // 注册成功直接将当前用户保存到session中
  62. request.getSession().setAttribute("user", user);
  63. request.getRequestDispatcher("/WEB-INF/pages/registerSuccess.jsp").forward(request,response);
  64. }
  65. }

3、激活帐户的Servlet(ActivateAccountServle)

  1. package org.study.accountactivate.web.servlet;
  2. import java.io.IOException;
  3. import javax.servlet.ServletException;
  4. import javax.servlet.http.HttpServlet;
  5. import javax.servlet.http.HttpServletRequest;
  6. import javax.servlet.http.HttpServletResponse;
  7. import org.study.accountactivate.dao.UserDao;
  8. import org.study.accountactivate.dao.impl.UserDaoImpl;
  9. import org.study.accountactivate.domail.User;
  10. import org.study.accountactivate.util.GenerateLinkUtils;
  11. /**
  12. * 帐户激活
  13. */
  14. public class ActivateAccountServlet extends HttpServlet {
  15. private static final long serialVersionUID = 1L;
  16. protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
  17. String idValue = request.getParameter("id");
  18. int id = -1;
  19. try {
  20. id = Integer.parseInt(idValue);
  21. } catch (NumberFormatException e) {
  22. throw new RuntimeException("无效的用户!");
  23. }
  24. UserDao userDao = UserDaoImpl.getInstance();
  25. User user = userDao.findUserById(id);// 得到要激活的帐户
  26. user.setActivated(GenerateLinkUtils.verifyCheckcode(user, request));// 校验验证码是否和注册时发送的一致,以此设置是否激活该帐户
  27. userDao.updateUser(user);
  28. request.getSession().setAttribute("user", user);
  29. request.getRequestDispatcher("/accountActivateUI").forward(request, response);
  30. }
  31. protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
  32. doGet(request, response);
  33. }
  34. }

4、操作用户的DAO接口与实现类(UserDao和UserDaoImpl类)

  1. package org.study.accountactivate.dao;
  2. import org.study.accountactivate.domail.User;
  3. public interface UserDao {
  4. void addUser(User user);
  5. void updateUser(User user);
  6. User findUserById(int id);
  7. User findUserByName(String userName);
  8. User findUserByNameOrEmail(String nameOrEmail);
  9. }
  10. package org.study.accountactivate.dao.impl;
  11. import java.util.Collection;
  12. import java.util.HashMap;
  13. import java.util.Iterator;
  14. import java.util.Map;
  15. import java.util.UUID;
  16. import org.study.accountactivate.dao.UserDao;
  17. import org.study.accountactivate.domail.User;
  18. public class UserDaoImpl implements UserDao {
  19. private static UserDaoImpl instance = new UserDaoImpl();
  20. private UserDaoImpl() {}
  21. public static UserDaoImpl getInstance() {
  22. return instance;
  23. }
  24. Map<Integer,User> users = new HashMap<Integer, User>();
  25. int nextId = 1;
  26. @Override
  27. public void addUser(User user) {
  28. user.setId(nextId++);
  29. user.setRandomCode(UUID.randomUUID().toString());
  30. users.put(user.getId(), user);
  31. }
  32. @Override
  33. public void updateUser(User user) {
  34. users.put(user.getId(), user);
  35. }
  36. @Override
  37. public User findUserById(int id) {
  38. return users.get(id);
  39. }
  40. @Override
  41. public User findUserByName(String userName) {
  42. Collection<User> userValues = users.values();
  43. for (Iterator<User> iterator = userValues.iterator();iterator.hasNext();) {
  44. User user = iterator.next();
  45. if (user.getUserName().equals(userName)) {
  46. return user;
  47. }
  48. }
  49. return null;
  50. }
  51. @Override
  52. public User findUserByNameOrEmail(String nameOrEmail) {
  53. Collection<User> userValues = users.values();
  54. for(Iterator<User> iterator = userValues.iterator();iterator.hasNext();) {
  55. User user = iterator.next();
  56. if (user.getEmail().equals(nameOrEmail) || user.getUserName().equals(nameOrEmail)) {
  57. return user;
  58. }
  59. }
  60. return null;
  61. }
  62. }

5、发送Email的工具类(EmailUtils,用于发送帐户激活链接和密码重置链接)

  1. package org.study.accountactivate.util;
  2. import java.io.IOException;
  3. import java.io.InputStream;
  4. import java.util.Date;
  5. import java.util.Properties;
  6. import javax.mail.Authenticator;
  7. import javax.mail.Message.RecipientType;
  8. import javax.mail.PasswordAuthentication;
  9. import javax.mail.Session;
  10. import javax.mail.Transport;
  11. import javax.mail.internet.InternetAddress;
  12. import javax.mail.internet.MimeMessage;
  13. import org.study.accountactivate.domail.User;
  14. public class EmailUtils {
  15. private static final String FROM = "xyang81@163.com";
  16. /**
  17. * 注册成功后,向用户发送帐户激活链接的邮件
  18. * @param user 未激活的用户
  19. */
  20. public static void sendAccountActivateEmail(User user) {
  21. Session session = getSession();
  22. MimeMessage message = new MimeMessage(session);
  23. try {
  24. message.setSubject("帐户激活邮件");
  25. message.setSentDate(new Date());
  26. message.setFrom(new InternetAddress(FROM));
  27. message.setRecipient(RecipientType.TO, new InternetAddress(user.getEmail()));
  28. message.setContent("<a href='" + GenerateLinkUtils.generateActivateLink(user)+"'>点击激活帐户</a>","text/html;charset=utf-8");
  29. // 发送邮件
  30. Transport.send(message);
  31. } catch (Exception e) {
  32. e.printStackTrace();
  33. }
  34. }
  35. /**
  36. * 发送重设密码链接的邮件
  37. */
  38. public static void sendResetPasswordEmail(User user) {
  39. Session session = getSession();
  40. MimeMessage message = new MimeMessage(session);
  41. try {
  42. message.setSubject("找回您的帐户与密码");
  43. message.setSentDate(new Date());
  44. message.setFrom(new InternetAddress(FROM));
  45. message.setRecipient(RecipientType.TO, new InternetAddress(user.getEmail()));
  46. message.setContent("要使用新的密码, 请使用以下链接启用密码:<br/><a href='" + GenerateLinkUtils.generateResetPwdLink(user) +"'>点击重新设置密码</a>","text/html;charset=utf-8");
  47. // 发送邮件
  48. Transport.send(message);
  49. } catch (Exception e) {
  50. e.printStackTrace();
  51. }
  52. }
  53. public static Session getSession() {
  54. Properties props = new Properties();
  55. props.setProperty("mail.transport.protocol", "smtp");
  56. props.setProperty("mail.smtp.host", "smtp.163.com");
  57. props.setProperty("mail.smtp.port", "25");
  58. props.setProperty("mail.smtp.auth", "true");
  59. Session session = Session.getInstance(props, new Authenticator() {
  60. @Override
  61. protected PasswordAuthentication getPasswordAuthentication() {
  62. String password = null;
  63. InputStream is = EmailUtils.class.getResourceAsStream("password.dat");
  64. byte[] b = new byte[1024];
  65. try {
  66. int len = is.read(b);
  67. password = new String(b,0,len);
  68. } catch (IOException e) {
  69. e.printStackTrace();
  70. }
  71. return new PasswordAuthentication(FROM, password);
  72. }
  73. });
  74. return session;
  75. }
  76. }

6、生成帐户激活、密码重设链接的工具类(GenerateLinkUtils)

  1. package org.study.accountactivate.util;
  2. import java.security.MessageDigest;
  3. import java.security.NoSuchAlgorithmException;
  4. import javax.servlet.ServletRequest;
  5. import org.study.accountactivate.domail.User;
  6. /**
  7. * 生成帐户激活、重新设置密码的链接
  8. */
  9. public class GenerateLinkUtils {
  10. private static final String CHECK_CODE = "checkCode";
  11. /**
  12. * 生成帐户激活链接
  13. */
  14. public static String generateActivateLink(User user) {
  15. return "http://localhost:8080/AccountActivate/activateAccount?id="
  16. + user.getId() + "&" + CHECK_CODE + "=" + generateCheckcode(user);
  17. }
  18. /**
  19. * 生成重设密码的链接
  20. */
  21. public static String generateResetPwdLink(User user) {
  22. return "http://localhost:8080/AccountActivate/resetPasswordUI?userName="
  23. + user.getUserName() + "&" + CHECK_CODE + "=" + generateCheckcode(user);
  24. }
  25. /**
  26. * 生成验证帐户的MD5校验码
  27. * @param user  要激活的帐户
  28. * @return 将用户名和密码组合后,通过md5加密后的16进制格式的字符串
  29. */
  30. public static String generateCheckcode(User user) {
  31. String userName = user.getUserName();
  32. String randomCode = user.getRandomCode();
  33. return md5(userName + ":" + randomCode);
  34. }
  35. /**
  36. * 验证校验码是否和注册时发送的验证码一致
  37. * @param user 要激活的帐户
  38. * @param checkcode 注册时发送的校验码
  39. * @return 如果一致返回true,否则返回false
  40. */
  41. public static boolean verifyCheckcode(User user,ServletRequest request) {
  42. String checkCode = request.getParameter(CHECK_CODE);
  43. return generateCheckcode(user).equals(checkCode);
  44. }
  45. private static String md5(String string) {
  46. MessageDigest md = null;
  47. try {
  48. md = MessageDigest.getInstance("md5");
  49. md.update(string.getBytes());
  50. byte[] md5Bytes = md.digest();
  51. return bytes2Hex(md5Bytes);
  52. } catch (NoSuchAlgorithmException e) {
  53. e.printStackTrace();
  54. }
  55. return null;
  56. }
  57. private static String bytes2Hex(byte[] byteArray)
  58. {
  59. StringBuffer strBuf = new StringBuffer();
  60. for (int i = 0; i < byteArray.length; i++)
  61. {
  62. if(byteArray[i] >= 0 && byteArray[i] < 16)
  63. {
  64. strBuf.append("0");
  65. }
  66. strBuf.append(Integer.toHexString(byteArray[i] & 0xFF));
  67. }
  68. return strBuf.toString();
  69. }
  70. }

7、实体类(User)

  1. package org.study.accountactivate.domail;
  2. public class User {
  3. // 编号
  4. private int id;
  5. // 用户名
  6. private String userName;
  7. // 密码
  8. private String password;
  9. // email
  10. private String email;
  11. // 是否激活
  12. private boolean activated;
  13. // 随机码(激活帐户与生成重设密码链接时使用)
  14. private String randomCode;
  15. public int getId() {
  16. return id;
  17. }
  18. public void setId(int id) {
  19. this.id = id;
  20. }
  21. public String getUserName() {
  22. return userName;
  23. }
  24. public void setUserName(String userName) {
  25. this.userName = userName;
  26. }
  27. public String getPassword() {
  28. return password;
  29. }
  30. public void setPassword(String password) {
  31. this.password = password;
  32. }
  33. public boolean isActivated() {
  34. return activated;
  35. }
  36. public void setActivated(boolean activated) {
  37. this.activated = activated;
  38. }
  39. public String getRandomCode() {
  40. return randomCode;
  41. }
  42. public void setRandomCode(String randomCode) {
  43. this.randomCode = randomCode;
  44. }
  45. public String getEmail() {
  46. return email;
  47. }
  48. public void setEmail(String email) {
  49. this.email = email;
  50. }
  51. }

功能实现步骤(忘记密码):

1、登录页面

  1. <form action="${pageContext.request.contextPath}/login" method="post">
  2. <span class="error" style="display: block;">${errors.loginError}</span>
  3. 用户名:<input type="text" name="userName" value="${param.userName}"><span class="error">${errors.userName}</span><br/>
  4. 密码:<input type="password" name="password"><span class="error">${errors.password}</span><br/>
  5. <input type="submit" value="登录">
  6. <a href="${pageContext.request.contextPath}/forgotPwdUI">忘记密码?</a>
  7. <a href="${pageContext.request.contextPath}/registerUI">注册</a>
  8. </form>

2、发送重设密码申请的页面

  1. <form action="${pageContext.request.contextPath}/forgotPwd" method="post">
  2. <span style="color: red">${requestScope.sendMailMsg}</span>
  3. 用户名/邮箱:<input type="text" name="userNameOrEmail" /><span style="color: red">${requestScope.errorMsg}</span><br/>
  4. <input type="submit" value="提交" /><a href=""></a>
  5. </form>

3、处理“发送重设密码链接“请求的Servlet(ForgotPwdServlet)

  1. package org.study.accountactivate.web.servlet;
  2. import java.io.IOException;
  3. import javax.servlet.ServletException;
  4. import javax.servlet.http.HttpServlet;
  5. import javax.servlet.http.HttpServletRequest;
  6. import javax.servlet.http.HttpServletResponse;
  7. import org.study.accountactivate.dao.UserDao;
  8. import org.study.accountactivate.dao.impl.UserDaoImpl;
  9. import org.study.accountactivate.domail.User;
  10. import org.study.accountactivate.util.EmailUtils;
  11. /**
  12. * 发送重设密码申请的链接
  13. */
  14. public class ForgotPwdServlet extends HttpServlet {
  15. private static final long serialVersionUID = 1L;
  16. protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
  17. String userNameOrEmail = request.getParameter("userNameOrEmail");
  18. UserDao userDao = UserDaoImpl.getInstance();
  19. User user = userDao.findUserByNameOrEmail(userNameOrEmail);
  20. if (user == null) {
  21. request.setAttribute("errorMsg", userNameOrEmail + ",不存在!");
  22. request.getRequestDispatcher("/forgotPwdUI").forward(request, response);
  23. return;
  24. }
  25. // 发送重新设置密码的链接
  26. EmailUtils.sendResetPasswordEmail(user);
  27. request.setAttribute("sendMailMsg", "您的申请已提交成功,请查看您的"+user.getEmail()+"邮箱。");
  28. request.getRequestDispatcher("/WEB-INF/pages/forgotPwdSuccess.jsp").forward(request, response);
  29. }
  30. protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
  31. doGet(request, response);
  32. }
  33. }

4、重新设置密码的页面

  1. <form action="${pageContext.request.contextPath}/resetPassword" method="post">
  2. <span class="error" style="display: block;">${errors.passwordError}</span>
  3. 用户名:<input type="text" name="userName" value="${userName}" readonly="readonly"/><br/>
  4. 新密码:<input type="password" name="newPassword" /><span class="error">${errors.newPassword }</span><br/>
  5. 确认新密码:<input type="password" name="newPassword2"/><span class="error">${errors.newPassword2 }</span><br/>
  6. <input type="submit" value="修改" />
  7. </form>

5、处理重新设置密码请求的Servlet(ResetPasswordServlet)

  1. package org.study.accountactivate.web.servlet;
  2. import java.io.IOException;
  3. import java.util.HashMap;
  4. import java.util.Map;
  5. import javax.servlet.ServletException;
  6. import javax.servlet.http.HttpServlet;
  7. import javax.servlet.http.HttpServletRequest;
  8. import javax.servlet.http.HttpServletResponse;
  9. import org.study.accountactivate.dao.UserDao;
  10. import org.study.accountactivate.dao.impl.UserDaoImpl;
  11. import org.study.accountactivate.domail.User;
  12. /**
  13. * 重新设置密码
  14. */
  15. public class ResetPasswordServlet extends HttpServlet {
  16. private static final long serialVersionUID = 1L;
  17. protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
  18. String userName = request.getParameter("userName");
  19. String newPassword = request.getParameter("newPassword");
  20. String newPassword2 = request.getParameter("newPassword2");
  21. Map<String,String> errors = new HashMap<String, String>();
  22. if (newPassword == null || "".equals(newPassword)) {
  23. errors.put("newPassword", "新密码不能为空!");
  24. }
  25. if (newPassword2 == null || "".equals(newPassword2)) {
  26. errors.put("newPassword2", "确认新密码不能为空!");
  27. }
  28. if (!newPassword.equals(newPassword2)) {
  29. errors.put("passwordError", "两次输入的密码不一致!");
  30. }
  31. if (!errors.isEmpty()) {
  32. request.setAttribute("errors", errors);
  33. request.getRequestDispatcher("/resetPasswordUI?userName=" + userName).forward(request, response);
  34. return;
  35. }
  36. UserDao userDao = UserDaoImpl.getInstance();
  37. User user = userDao.findUserByName(userName);
  38. user.setPassword(newPassword);
  39. request.getRequestDispatcher("/WEB-INF/pages/resetPasswordSuccess.jsp").forward(request, response);
  40. }
  41. protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
  42. doGet(request, response);
  43. }
  44. }

帐户激活操作流程:

1)、注册页面

JavaMail学习笔记(七)、帐号激活与忘记密码 实例(zhuan)

2)、注册成功页面

JavaMail学习笔记(七)、帐号激活与忘记密码 实例(zhuan)

3)、帐户未激活,登录后的界面

JavaMail学习笔记(七)、帐号激活与忘记密码 实例(zhuan)

4)、前往邮箱中激活帐户

JavaMail学习笔记(七)、帐号激活与忘记密码 实例(zhuan)

5)、激活成功

JavaMail学习笔记(七)、帐号激活与忘记密码 实例(zhuan)

6)、帐户已激活,登录后的界面

JavaMail学习笔记(七)、帐号激活与忘记密码 实例(zhuan)

忘记密码操作流程:

1)、登录页面(点击“忘记密码”链接,进入重设密码页面)

JavaMail学习笔记(七)、帐号激活与忘记密码 实例(zhuan)

2、重设密码申请页面(输入用户名或邮箱,点击“提交”按钮)

JavaMail学习笔记(七)、帐号激活与忘记密码 实例(zhuan)

3、重设密码申请成功页面

JavaMail学习笔记(七)、帐号激活与忘记密码 实例(zhuan)

4、邮箱中重设密码的链接

JavaMail学习笔记(七)、帐号激活与忘记密码 实例(zhuan)

5、重新设置密码页面

JavaMail学习笔记(七)、帐号激活与忘记密码 实例(zhuan)

6、密码重新设置成功页面

JavaMail学习笔记(七)、帐号激活与忘记密码 实例(zhuan)

源码下载地址:http://download.csdn.net/detail/xyang81/4510396

http://blog.csdn.net/xyang81/article/details/7727141

JavaMail学习笔记(七)、帐号激活与忘记密码 实例(zhuan)的更多相关文章

  1. 转:java 帐号激活与忘记密码 实例

    原文链接:http://endual.iteye.com/blog/1613679 一.帐户激活   在 很多时候,在某些网站注册一个用户之后,网站会给这个用户注册时填写的email地址发送一封帐户激 ...

  2. linux初级学习笔记七:linux用户管理,密码和组命令详解!&lpar;视频序号:04&lowbar;1&rpar;

    本节学习的命令: 用户管理命令:useradd,userdel,id,finger,usermod,chsh,chfn,passwd,pwck, 组管理命令:groupadd,groupmod,gro ...

  3. &period;NET Remoting学习笔记(二)激活方式

    目录 .NET Remoting学习笔记(一)概念 .NET Remoting学习笔记(二)激活方式 .NET Remoting学习笔记(三)信道 参考:百度百科  ♂风车车.Net 激活方式概念 在 ...

  4. (转)Qt Model&sol;View 学习笔记 &lpar;七&rpar;——Delegate类

    Qt Model/View 学习笔记 (七) Delegate  类 概念 与MVC模式不同,model/view结构没有用于与用户交互的完全独立的组件.一般来讲, view负责把数据展示 给用户,也 ...

  5. JavaMail学习笔记

    适逢计算机网络课程设计,本着挑战自己的态度,选择了一个从未接触的东西:邮箱客户端代理软件的设计.由于对相关协议非常陌生,只能依靠查找资料完成,在学习过程中碰到了一个非常好的博客,故向大家推荐一下. 一 ...

  6. Learning ROS for Robotics Programming Second Edition学习笔记&lpar;七&rpar; indigo PCL xtion pro live

    中文译著已经出版,详情请参考:http://blog.csdn.net/ZhangRelay/article/category/6506865 Learning ROS forRobotics Pro ...

  7. SQL反模式学习笔记19 使用&ast;号,隐式的列

    目标:减少输入 反模式:捷径会让你迷失方向 使用通配符和未命名的列能够达到减少输入的目的,但是这个习惯会带来一些危害. 1.破坏代码重构:增加一列后,使用隐式的Insert插入语句报错: 2.查询中使 ...

  8. Typescript 学习笔记七:泛型

    中文网:https://www.tslang.cn/ 官网:http://www.typescriptlang.org/ 目录: Typescript 学习笔记一:介绍.安装.编译 Typescrip ...

  9. python3&period;4学习笔记&lpar;七&rpar; 学习网站博客推荐

    python3.4学习笔记(七) 学习网站博客推荐 深入 Python 3http://sebug.net/paper/books/dive-into-python3/<深入 Python 3& ...

随机推荐

  1. JNDI

    这两天研究了一下 context.lookup("java:comp/env/XXX")和直接context.lookup("XXX")的区别 网上关于这两个的 ...

  2. &lbrack;原创&rsqb;WPF资源Binding自定义集合类。

    简单介绍一下Wpf资源字典: 每个WPF界面元素都有一个名为Resource的属性,这个属性继承至FrameworkElement类,其类型为ResourceDictionary.ResourceDi ...

  3. MVC5&plus;EF6 简易版CMS(非接口) 第一章:新建项目

    目录 简易版CMS后台管理系统开发流程 MVC5+EF6 简易版CMS(非接口) 第一章:新建项目 MVC5+EF6 简易版CMS(非接口) 第二章:建数据模型 MVC5+EF6 简易版CMS(非接口 ...

  4. vs2015上配置Armadillo&plus;openBlas

    首先去官网下载 Armadillo http://arma.sourceforge.net/download.html#windows 我下载的是armadillo-7.500.0.tar.xz 解压 ...

  5. redis 中的key值过期后,触发通知事件

    1.创建springboot工程,创建监听类 maven配置 <dependencies> <dependency> <groupId>org.springfram ...

  6. 【01】团饱和图:(一)EHM定理

    团饱和图:(一)EHM定理 据A. Hajnal考证,术语"饱和性",即saturation,最早由前苏联数学家A. A. Zykov在1949年引入,用于研究线性复形,但是他的工 ...

  7. jsp中文乱码解决办法

    一.JSP页面显示乱码 二.表单提交中文时出现乱码 三.数据库连接 大家在JSP的开发过程中,经常出现中文乱码的问题,可能一至困扰着您,我现在把我在JSP开发中遇到 的中文乱码的问题及解决办法写出来供 ...

  8. c&num;元组举例

    元组的概要: 数组合并了相同类型的对象,而元组合并了不同类型的对象.元组起源于函数编程语言(如F#) ,在 这些语言中频繁使用元组.在N盯4中,元组可通过.NET Fmmework用于所有的NET语言 ...

  9. trident介绍

    (一)理论基础 很多其它理论以后再补充,或者參考书籍 1.trident是什么? Trident is a high-level abstraction for doing realtime comp ...

  10. L165

    New evidence of how the Norse became long-distance marinersAccording to the saga of Erik the Red, “s ...