一、帐户激活

 

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

这个功能是怎么做到的呢,其实实现也是很简单的,说白了就是一个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)、注册页面

2)、注册成功页面

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

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

5)、激活成功

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

忘记密码操作流程:

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

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

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

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

5、重新设置密码页面

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

源码下载地址: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用户管理,密码和组命令详解!(视频序号:04_1)

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

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

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

  4. (转)Qt Model/View 学习笔记 (七)——Delegate类

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

  5. JavaMail学习笔记

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

  6. Learning ROS for Robotics Programming Second Edition学习笔记(七) indigo PCL xtion pro live

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

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

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

  8. Typescript 学习笔记七:泛型

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

  9. python3.4学习笔记(七) 学习网站博客推荐

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

随机推荐

  1. uva 11212

    非原创!!! 原作者地址:http://www.hardbird.net/?p=238

  2. ELK日志系统:Elasticsearch + Logstash + Kibana 搭建教程(转)

    环境:OS X 10.10.5 + JDK 1.8 步骤: 一.下载ELK的三大组件 Elasticsearch下载地址: https://www.elastic.co/downloads/elast ...

  3. Swift - 使用表格组件(UITableView)实现单列表

    1,样例说明: (1)列表内容从Controls.plist文件中读取,类型为Array. (2)点击列表项会弹出消息框显示该项信息. (3)按住列表项向左滑动,会出现删除按钮.点击删除即可删除该项. ...

  4. protobuf-2.5.0.tar.gz的下载与安装

    1.下载 hadoop使用protocol buffer进行通信,须要下载和安装protobuf-2.5.0.tar.gz.因为如今protobuf-2.5.0.tar.gz已经无法在官网https: ...

  5. A*寻路算法的实现

    原理:http://www.cppblog.com/christanxw/archive/2006/04/07/5126.html 算法理论请到原理这个传送门,代码中的注释,已经比较详细,所以我不会讲 ...

  6. SVN的项目管理

    基于SVN的项目管理——集中与分散   我们在此处不讨论 GIT 比 SVN 好多少,也不讨论 Maven 和 Gradle 哪个好用,基于现有的开发环境,大多数公司还是采用 SVN + Maven ...

  7. 14.4.4 Configuring the Memory Allocator for InnoDB InnoDB 配置内存分配器

    14.4.4 Configuring the Memory Allocator for InnoDB InnoDB 配置内存分配器 当InnoDB 被开发, 内分配齐 提供了与操作系统和运行库往往缺乏 ...

  8. hdu4055 Number String

    Number String Time Limit: 10000/5000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others) Tota ...

  9. 并发编程实践五:ReentrantLock

    ReentrantLock是一个可重入的相互排斥锁,实现了接口Lock,和synchronized相比,它们提供了同样的功能.但ReentrantLock使用更灵活.功能更强大,也更复杂.这篇文章将为 ...

  10. JNI生成so

    软件:android-ndk-r8 推荐使用这个版本,可以直接不用安装Cygwin软件就可以编译. 然后在系统环境变量中path选项中添加安装路径,比如我的:C:\android-ndk-r8: 然后 ...