一.先说思路javascript
//1.数据库加三个字段,state:(0:未激活,1:激活成功),ActiCode:(放激活码),token_exptime(过时时间,用来验证激活邮件是否过时)html
//2.用户填写资料,点击注册,插入数据成功,state字段默认是0,同时生成一个ActiCode(用传过来的邮箱、密码、和当前时间加密造成)也存入数据库java
//3.发送邮件。。。提示用户登陆邮箱激活。。。邮件中带一个激活成功页的URL,URL里有两个参数(1,用户ID,2:激活码)web
//4.用户登陆邮箱点击连接,来处处理激活的业务逻辑页面或Servlet,获得URL中两个参数,以这两个参数为条件查询数据库里的数据,若是有,取当前时间和以前存入数据库的过时时间做比较,看是否过时,过时,删除数据库中该条记录,并转到失败页面,没过时,查看连接传过来的激活码与数据库字段激活码是否一致,不一致,一样删除数据库中该条记录,并跳转到激活失败界面,一致,则将字段state为1,激活成功,转到激活成功页。。。sql
2、具体实现代码数据库
1.首先,准备一个简单的测试页面浏览器
<body> <div id="main" style="margin:0 auto;width:500px;"> <form id="reg" action="user.action?op=reg" method="post"> <p> E-mail:<input type="text" class="input" name="email" id="email"> </p> <p> 密 码:<input type="password" class="input" name="pwd" id="pwd"> </p> <p> <input type="submit" class="btn" value="提交注册" > </p> </form> </div> </body>
2.点击提交注册,来到user.action?op=reg,注意带的参数op指我要作的操做,用于后面的Servlet作判断该作什么操做,下面的代码完成了造成激活码、过时时间等表示当前注册用户的状态的信息存入数据库并发送邮件的过程。(邮件内容自定义,能够忽略个人)服务器
1 package com.nh.web.servlets; 2 3 import java.io.IOException; 4 import java.io.PrintWriter; 5 import java.sql.SQLException; 6 import java.text.SimpleDateFormat; 7 import java.util.ArrayList; 8 import java.util.Calendar; 9 import java.util.Date; 10 import java.util.List; 11 import java.util.UUID; 12 13 import javax.naming.NamingException; 14 import javax.servlet.ServletException; 15 import javax.servlet.http.HttpServlet; 16 import javax.servlet.http.HttpServletRequest; 17 import javax.servlet.http.HttpServletResponse; 18 19 import com.nh.dao.DBHelper; 20 import com.nh.utils.Encrypt; 21 import com.nh.utils.SendEmail; 22 23 public class UserServlet extends CommonServlet { 24 25 public void doPost(HttpServletRequest request, HttpServletResponse response) 26 throws ServletException, IOException { 27 // 取出op 28 String op = request.getParameter("op"); 29 // 判断op是什么,调用不一样的方法作处理 30 try { 31 if (op != null && !"".equals(op)) { 32 if ("reg".equals(op)) { 33 regOP(request, response); 34 } 35 } else { 36 37 } 38 } catch (Exception e) { 39 e.printStackTrace(); 40 response.sendRedirect("common/500.jsp"); 41 } 42 } 43 44 private void regOP(HttpServletRequest request, HttpServletResponse response) throws IOException, SQLException, NamingException { 45 // 1.数据库加两个字,state字段(0:未激活,1:激活成功),ActiCode:(放激活码) 46 // 2.用户填写资料,插入数据成功,state字段默认是0,同时生成一个ActiCode也存入数据库 47 // 3.提示用户激活。。。发送邮件。。。邮件中带一个激活成功页的URL,URL里有两个参数(1,用户ID,2:激活码) 48 // 4.用户点击连接,回到激活成功页。。。激活成功页的Load事件,获得两个参数,以这两个参数为条件查询数据库里的数据,若是有,修改字段state为1,反之。。提示激活失败,从新激活。。 49 50 String email=request.getParameter("email"); 51 String pwd=Encrypt.md5(request.getParameter("pwd")); 52 Calendar c = Calendar.getInstance(); 53 //如今的时间(单位:毫秒) 54 //TODO:时间换算问题,如何处理int和long之间的关系 55 long time = c.getTimeInMillis(); 56 57 //建立激活码 58 String token=Encrypt.md5(email+pwd+time); 59 //过时时间为24小时后 60 // int token_exptime=(int)(time+1000*60*60*24); 61 String token_exptime=(time+1000*20)+""; //这里测试是用的20秒 62 63 String id=UUID.randomUUID().toString(); 64 String sql="insert into tb_user(id,username,pwd,token,token_exptime,regtime,status) values (?,?,?,?,?,sysdate,0)"; 65 66 List<Object> params=new ArrayList<Object>(); 67 params.add(id); 68 params.add(email); 69 params.add(pwd); 70 params.add(token); 71 params.add(token_exptime); 72 73 DBHelper db=new DBHelper(); 74 int r=db.doUpdate(sql, params); //保存注册信息 75 76 if( r>0 ){ 77 //发送邮件 78 ///邮件的内容 79 SimpleDateFormat sdf=new SimpleDateFormat("yyyy-MM-dd"); 80 81 StringBuffer sb=new StringBuffer("<div style=\"width:660px;overflow:hidden;border-bottom:1px solid #bdbdbe;\"><div style=\"height:52px;overflow:hidden;border:1px solid #464c51;background:#353b3f url(http://www.lofter.com/rsc/img/email/hdbg.png);\"><a href=\"http://www.lofter.com?mail=qbclickbynoticemail_20120626_01\" target=\"_blank\" style=\"display:block;width:144px;height:34px;margin:10px 0 0 20px;overflow:hidden;text-indent:-2000px;background:url(http://www.lofter.com/rsc/img/email/logo.png) no-repeat;\">LOFTER</a></div>"+"<div style=\"padding:24px 20px;\">您好,"+email+"<br/><br/>LOFTER是一款\"专一兴趣、分享创做\"的轻博客产品,旨在为\"热爱记录生活、追求时尚品质、崇尚自由空间\"的你,打造一个全新而定展现平台!<br/><br/>请点击下面连接激活帐号,24小时生效,不然从新注册帐号,连接只能使用一次,请尽快激活!</br>"); 82 sb.append("<a href=\"http://localhost:8080/mailtest/emailcheck.action?op=activate&id="); 83 sb.append(id); 84 sb.append("&token="); 85 sb.append(token); 86 sb.append("\">http://localhost:8080/mailtest/emailcheck.action?op=activate&id="); 87 sb.append(id); 88 sb.append("&token="); 89 sb.append(token); 90 sb.append("</a>"+"<br/>若是以上连接没法点击,请把上面网页地址复制到浏览器地址栏中打开<br/><br/><br/>LOFTER,专一兴趣,分享创做<br/>"+sdf.format(new Date())+ "</div></div>" ); 91 92 //发送邮件 93 SendEmail.send(email, sb.toString()); 94 } 95 96 response.sendRedirect("doEmail.action?op=emaillogin&email="+email+"&pwd="+pwd); 97 98 } 99 100 }
发送邮件的代码,这里须要导入javax.mail的包,即mail.jar,若是发件人邮箱是QQ邮箱还要去QQ邮箱开启smtp和其余两个协议,我这里用的163邮箱就不须要设置session
1 package com.nh.utils; 2 3 import java.util.Date; 4 import java.util.Properties; 5 6 import javax.mail.Authenticator; 7 import javax.mail.Message; 8 import javax.mail.MessagingException; 9 import javax.mail.PasswordAuthentication; 10 import javax.mail.Session; 11 import javax.mail.Transport; 12 import javax.mail.internet.InternetAddress; 13 import javax.mail.internet.MimeMessage; 14 15 16 /** 17 * 18 * @author Qixuan.Chen 19 */ 20 public class SendEmail { 21 22 public static final String HOST = "smtp.163.com"; 23 // public static final String PROTOCOL = "smtp"; 24 // public static final int PORT = 25; 25 26 public static final String FROM = "xxxx@163.com";//发件人的email 27 public static final String PWD = "xxxx";//发件人密码 28 29 30 /** 31 * 获取Session 32 * @return 33 */ 34 private static Session getSession() { 35 Properties props = new Properties(); 36 props.put("mail.smtp.host", HOST);//设置服务器地址 37 // props.put("mail.store.protocol" , PROTOCOL);//设置协议 38 // props.put("mail.smtp.port", PORT);//设置端口 39 props.put("mail.smtp.auth" , "true"); 40 41 Authenticator authenticator = new Authenticator() { 42 43 @Override 44 protected PasswordAuthentication getPasswordAuthentication() { 45 return new PasswordAuthentication(FROM, PWD); 46 } 47 48 }; 49 Session session = Session.getDefaultInstance(props , authenticator); 50 51 return session; 52 } 53 54 public static void send(String toEmail , String content) { 55 Session session = getSession(); 56 try { 57 // System.out.println("--send--"+content); 58 // Instantiate a message 59 Message msg = new MimeMessage(session); 60 61 //Set message attributes 62 msg.setFrom(new InternetAddress(FROM)); 63 InternetAddress[] address = {new InternetAddress(toEmail)}; 64 msg.setRecipients(Message.RecipientType.TO, address); 65 msg.setSubject("帐号激活邮件"); 66 msg.setSentDate(new Date()); 67 msg.setContent(content , "text/html;charset=utf-8"); 68 69 //Send the message 70 Transport.send(msg); 71 } 72 catch (MessagingException mex) { 73 mex.printStackTrace(); 74 } 75 } 76 77 }
这是收到的激活邮件并发
根据用户所填邮箱跳转相应邮箱登陆地址的代码
1 package com.nh.web.servlets; 2 3 import java.io.IOException; 4 import java.io.PrintWriter; 5 6 import javax.servlet.ServletException; 7 import javax.servlet.http.HttpServlet; 8 import javax.servlet.http.HttpServletRequest; 9 import javax.servlet.http.HttpServletResponse; 10 11 public class DoEmailLoginServlet extends CommonServlet { 12 13 public void doPost(HttpServletRequest request, HttpServletResponse response) 14 throws ServletException, IOException { 15 String op = request.getParameter("op"); 16 // 判断op是什么,调用不一样的方法作处理 17 try { 18 if (op != null && !"".equals(op)) { 19 if ("emaillogin".equals(op)) { 20 emailloginOP(request, response); 21 } 22 } else { 23 24 } 25 } catch (Exception e) { 26 e.printStackTrace(); 27 response.sendRedirect("common/500.jsp"); 28 } 29 } 30 31 private void emailloginOP(HttpServletRequest request, 32 HttpServletResponse response) throws IOException { 33 //判断用户邮箱是什么,跳到指定邮箱登录界面 34 String email=request.getParameter("email"); //572480349@qq.com 35 String pwd=request.getParameter("pwd"); 36 String addrstr=email.split("@")[1]; //qq.com 37 38 if( "qq.com".equals(addrstr)){ 39 addrstr="https://mail.qq.com"; 40 }else if( "163.com".equals(addrstr)){ 41 addrstr="http://mail.163.com/"; 42 }else if( "126.com".equals(addrstr)){ 43 addrstr="http://www.126.com/"; 44 }else if( "sina.com".equals(addrstr)){ 45 addrstr="http://mail.sina.com.cn/"; 46 }else if( "hotmail.com".equals(addrstr)){ 47 addrstr="https://login.live.com"; 48 } 49 50 response.sendRedirect("emailaction.jsp?email="+email+"&pwd="+pwd+"&addrstr="+addrstr); 51 } 52 53 }
具体页面我就不一一给了,直接上激活验证代码吧
1 package com.nh.web.servlets; 2 3 import java.io.IOException; 4 import java.io.PrintWriter; 5 import java.lang.reflect.InvocationTargetException; 6 import java.sql.SQLException; 7 import java.util.ArrayList; 8 import java.util.Calendar; 9 import java.util.List; 10 11 import javax.naming.NamingException; 12 import javax.servlet.ServletException; 13 import javax.servlet.http.HttpServlet; 14 import javax.servlet.http.HttpServletRequest; 15 import javax.servlet.http.HttpServletResponse; 16 17 import com.lofter.bean.User; 18 import com.nh.dao.DBHelper; 19 import com.nh.utils.DataExistAlreadyException; 20 21 public class EmailActivateCheckServlet extends CommonServlet { 22 23 public void doPost(HttpServletRequest request, HttpServletResponse response) 24 throws ServletException, IOException { 25 // 取出op 26 String op = request.getParameter("op"); 27 // 判断op是什么,调用不一样的方法作处理 28 try { 29 if (op != null && !"".equals(op)) { 30 if( "activate".equals(op)){ 31 activateOP(request,response); 32 } 33 } else { 34 35 } 36 } catch (Exception e) { 37 e.printStackTrace(); 38 response.sendRedirect("common/500.jsp"); 39 } 40 } 41 42 private void activateOP(HttpServletRequest request, 43 HttpServletResponse response) throws InstantiationException, IllegalAccessException, IllegalArgumentException, InvocationTargetException, Exception { 44 //获取参数token的值,即激活识别码。 45 //将它与数据表中的用户信息进行查询对比,若是有相应的数据集,判断是否过时,若是在有效期内则将对应的用户表中字段status设置1,即已激活,这样就完成了激活功能。 46 47 String id=request.getParameter("id"); 48 String token=request.getParameter("token"); 49 Calendar c = Calendar.getInstance(); 50 //如今的时间(单位:毫秒) 51 long curtime = c.getTimeInMillis(); 52 53 String sql="select id,token_exptime,token,username,pwd from tb_user where status=0 and token=?"; 54 List<Object> params=new ArrayList<Object>(); 55 params.add( token ); 56 57 DBHelper db=new DBHelper(); 58 User u=db.findSingleObject(User.class, sql, params); 59 String email=u.getUsername(); 60 String pwd=u.getPwd(); 61 if( u!=null ){ 62 long token_exptime=Long.parseLong(u.getToken_exptime()); 63 if( curtime>token_exptime ){ 64 //激活码过时,先删除该用户记录,而后从新发送邮件 65 sql="delete from tb_user where id='"+u.getId()+"'"; 66 db.doUpdate(sql, null); 67 response.sendRedirect("actionfailer.jsp?email="+email+"&pwd="+pwd); 68 // throw new DataExistAlreadyException("激活码已过时!"); 69 return; 70 }else{ 71 //验证激活码是否正确 72 if( token.equals(u.getToken())){ 73 //激活成功, //并更新用户的激活状态,为已激活 74 sql="update tb_user set status=1 where id='"+u.getId()+"'"; 75 db.doUpdate(sql, null); 76 response.sendRedirect("actionsuccess.jsp"); 77 }else{ 78 sql="delete from tb_user where id='"+u.getId()+"'"; 79 db.doUpdate(sql, null); 80 response.sendRedirect("actionfailer.jsp?email="+email+"&pwd="+pwd); 81 return; 82 // throw new DataExistAlreadyException("激活码不正确"); 83 } 84 } 85 } 86 87 } 88 89 } 90 91 92 93 package com.nh.web.servlets; 94 95 import java.io.IOException; 96 import java.io.PrintWriter; 97 98 import javax.servlet.ServletContext; 99 import javax.servlet.ServletException; 100 import javax.servlet.http.HttpServlet; 101 import javax.servlet.http.HttpServletRequest; 102 import javax.servlet.http.HttpServletResponse; 103 import javax.servlet.http.HttpSession; 104 105 106 public abstract class CommonServlet extends HttpServlet { 107 private static final long serialVersionUID = 3893961453320250657L; 108 109 private String saveFilePath=""; 110 protected String basePath=""; 111 112 113 @Override 114 protected void doGet(HttpServletRequest req, HttpServletResponse resp) 115 throws ServletException, IOException { 116 doPost(req,resp); 117 } 118 119 @Override 120 protected void service(HttpServletRequest req, HttpServletResponse resp) 121 throws ServletException, IOException { 122 123 saveFilePath=req.getRealPath("/"); 124 HttpSession session=req.getSession(); 125 ServletContext application=session.getServletContext(); 126 if( application.getAttribute("basePath")!=null ){ 127 basePath=(String) application.getAttribute("basePath"); 128 } 129 130 super.service(req, resp); 131 } 132 133 134 } 135 136 137 package com.lofter.bean; 138 139 import java.io.Serializable; 140 import java.util.Date; 141 142 public class User implements Serializable { 143 144 private static final long serialVersionUID = -1989259749641485708L; 145 146 private String id; 147 private String username; // --帐户 148 private String pwd; // --密码 149 private String nickname; // --名称 150 private String autograph; // --我的签名 151 private String head; // --头像 152 private Date regtime; // --注册时间 153 154 private String token; // --帐号激活码 155 private String token_exptime; // --激活码有效期 156 private Integer status; // --激活状态 ,0-未激活,1-已激活 157 158 public User() { 159 super(); 160 } 161 162 163 164 public User(String id, String username, String pwd, String nickname, 165 String autograph, String head, Date regtime, String token, 166 String token_exptime, Integer status) { 167 super(); 168 this.id = id; 169 this.username = username; 170 this.pwd = pwd; 171 this.nickname = nickname; 172 this.autograph = autograph; 173 this.head = head; 174 this.regtime = regtime; 175 this.token = token; 176 this.token_exptime = token_exptime; 177 this.status = status; 178 } 179 180 181 182 public String getId() { 183 return id; 184 } 185 186 public void setId(String id) { 187 this.id = id; 188 } 189 190 public String getUsername() { 191 return username; 192 } 193 194 public void setUsername(String username) { 195 this.username = username; 196 } 197 198 public String getPwd() { 199 return pwd; 200 } 201 202 public void setPwd(String pwd) { 203 this.pwd = pwd; 204 } 205 206 public String getNickname() { 207 return nickname; 208 } 209 210 public void setNickname(String nickname) { 211 this.nickname = nickname; 212 } 213 214 public String getAutograph() { 215 return autograph; 216 } 217 218 public void setAutograph(String autograph) { 219 this.autograph = autograph; 220 } 221 222 public String getHead() { 223 return head; 224 } 225 226 public void setHead(String head) { 227 this.head = head; 228 } 229 230 public Date getRegtime() { 231 return regtime; 232 } 233 234 public void setRegtime(Date regtime) { 235 this.regtime = regtime; 236 } 237 238 public static long getSerialversionuid() { 239 return serialVersionUID; 240 } 241 242 public String getToken() { 243 return token; 244 } 245 246 public void setToken(String token) { 247 this.token = token; 248 } 249 250 public String getToken_exptime() { 251 return token_exptime; 252 } 253 254 public void setToken_exptime(String token_exptime) { 255 this.token_exptime = token_exptime; 256 } 257 258 public Integer getStatus() { 259 return status; 260 } 261 262 public void setStatus(Integer status) { 263 this.status = status; 264 } 265 266 267 268 }