一.先说思路
//1.数据库加三个字段,state:(0:未激活,1:激活成功),ActiCode:(放激活码),token_exptime(过期时间,用来验证激活邮件是否过期)
//2.用户填写资料,点击注册,插入数据成功,state字段默认是0,同时生成一个ActiCode(用传过来的邮箱、密码、和当前时间加密形成)也存入数据库
//3.发送邮件。。。提示用户登录邮箱激活。。。邮件中带一个激活成功页的URL,URL里有两个参数(1,用户ID,2:激活码)
//4.用户登录邮箱点击链接,来到处理激活的业务逻辑页面或Servlet,得到URL中两个参数,以这两个参数为条件查询数据库里的数据,如果有,取当前时间和之前存入数据库的过期时间作比较,看是否过期,过期,删除数据库中该条记录,并转到失败页面,没过期,查看链接传过来的激活码与数据库字段激活码是否一致,不一致,同样删除数据库中该条记录,并跳转到激活失败界面,一致,则将字段state为1,激活成功,转到激活成功页。。。
二、具体实现代码
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邮箱就不需要设置
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 }