原文地址:http://blog.csdn.net/qq_26525215/article/details/52276168
网站用户注册:
主要实现如下两个功能:
1、用户在网站上注册完成后给用户发一封邮件。
2、用户通过邮件激活后才可以登录。
思路:
首先需要一个思路:
用户在前台点击注册,向servlet提交请求,把用户提交过来的信息封装成一个JavaBean(需要的信息有name,pwd,email这3个是用户填写的,我们帮用户生成的是id和一个邮箱激活链接地址的唯一标识码acode,还要一个用来识别用户是否已经点击链接的变量active)。
servlet调用service层,service层再去调用dao层,dao再去访问数据库,
生成2个uuid分别赋值给id和acode。通过用户是否点击激活链接(url?acode=******
)新写一个servlet来判断用户是否点击链接激活。
用户点了激活链接后,再自动跳转到登录页面!
【数据库的字段名和JavaBean的成员变量名最好统一,方便自己写代码与查错】
通过下面的图片可以更好的帮你理解:
实例:
源代码
创建users表:
先准备好数据库hncu:
创建一个表:
create table users( id varchar(32) primary key, name varchar(30), pwd varchar(32), email varchar(80), active char(1), acode varchar(32));
需要准备的JAR包
链接:-如果链接失效-可以私信我
https://github.com/yangchunjian/Java/tree/master/myMailWeb/WebRoot/WEB-INF/lib
发送邮件的线程:MySendMailThread
必须用线程来做,否则网站的效率会很差。
可以想象,如果不用线程,直接servlet 中在用户请求注册后给他发邮件,然后再跳转页面,这明显很慢吧,我们需要去请求邮箱的服务器,然后邮箱的服务器需要向令一个邮箱请求,然后最后才能返回到我们这里,才能页面返回内容,这样,用户岂不是要等很久。我们如果用多线程,只要把那个线程new出来就可以了,要怎么去发邮件是那个线程的事,与我这个主线程没关系,我负责直接通知用户邮件发送成功就可以了,这样速度显然快多了。
package cn.hncu.reg.sendMail;import java.security.GeneralSecurityException;import java.util.Properties;import javax.mail.Authenticator;import javax.mail.Message.RecipientType;import javax.mail.MessagingException;import javax.mail.PasswordAuthentication;import javax.mail.Session;import javax.mail.Transport;import javax.mail.internet.AddressException;import javax.mail.internet.InternetAddress;import javax.mail.internet.MimeMessage;import com.sun.mail.util.MailSSLSocketFactory;import cn.hncu.domain.User;public class MySendMailThread extends Thread { private User user = null; public MySendMailThread(User user) { this.user = user; } @Override public void run() { Properties p = new Properties(); p.setProperty("mail.host", "smtp.qq.com"); p.setProperty("mail.smtp.auth", "true"); p.setProperty("mail.transport.protocol", "smtp"); MailSSLSocketFactory sf = null; try { sf = new MailSSLSocketFactory(); } catch (GeneralSecurityException e1) { e1.printStackTrace(); } sf.setTrustAllHosts(true); p.put("mail.smtp.ssl.enable", "true"); p.put("mail.smtp.ssl.socketFactory", sf); Session session = Session.getDefaultInstance(p, new Authenticator() { @Override protected PasswordAuthentication getPasswordAuthentication() { PasswordAuthentication pa = new PasswordAuthentication( "chenhaoxiang0117", "jnj***********ab"); return pa; } }); session.setDebug(true); try { MimeMessage msg = new MimeMessage(session); msg.setFrom(new InternetAddress("61******29@qq.com")); msg.setRecipient(RecipientType.TO, new InternetAddress(user.getEmail())); msg.setSubject(user.getName() + ",欢迎注册***账号,请点击链接激活账号"); StringBuilder sbd = new StringBuilder(); sbd.append(user.getName() + "<br/>欢迎!请确认此邮件地址以激活您的账号。<br/>"); sbd.append("<font color='red'><a href='http://192.168.1.102:8080/myMailWeb/ActiveServlet?acode=" + user.getAcode() + "' target='_blank'"); sbd.append(">立即激活</a></font><br/>"); sbd.append("或者点击下面链接:<br/>"); sbd.append("http://192.168.1.102:8080/myMailWeb/ActiveServlet?acode=" + user.getAcode() + "<br/>"); sbd.append("这是一封自动发送的邮件;如果您并未要求但收到这封信件,您不需要进行任何操作。"); msg.setContent(sbd.toString(), "text/html;charset=utf-8"); Transport.send(msg); System.out.println("给" + user.getEmail() + "发送邮件成功。"); } catch (AddressException e) { e.printStackTrace(); } catch (MessagingException e) { e.printStackTrace(); } }}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
- 39
- 40
- 41
- 42
- 43
- 44
- 45
- 46
- 47
- 48
- 49
- 50
- 51
- 52
- 53
- 54
- 55
- 56
- 57
- 58
- 59
- 60
- 61
- 62
- 63
- 64
- 65
- 66
- 67
- 68
- 69
- 70
- 71
- 72
- 73
- 74
- 75
- 76
- 77
- 78
- 79
- 80
- 81
- 82
- 83
- 84
- 85
- 86
- 87
- 88
- 89
- 90
- 91
- 92
- 93
- 94
- 95
- 96
- 97
- 98
- 99
- 100
- 101
- 102
- 103
- 104
index.jsp:
主页,表单提交通过按钮点击事件监听来提交表单。
然后分别设置表单的action值,这样一个表单可以实现访问多个servlet。
如果要做好一点,可以添加ajax格式实时验证和验证码验证
<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%><%@taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c"%><!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"><html> <head> <title>带邮箱激活的注册模块</title> <script type="text/javascript"> function reg(){ document.forms[0].action="<c:url value='RegServlet'/>"; document.forms[0].submit(); } function login(){ document.forms[0].action="<c:url value='LoginServlet'/>"; document.forms[0].submit(); } </script> </head> <body> <c:if test="${!empty sessionScope.error}"> 登录失败! <c:remove var="error" scope="session"/> </c:if> <c:if test="${empty sessionScope.user}" var="boo"> <form action="" method="post"> 姓名:<input type="text" name="name" /> <br/> 密码:<input type="password" name="pwd" /> <br/> 邮箱:<input type="text" name="email" />-登录不用填写邮箱 <br/> <input type="button" value="注册" onclick="reg();"/> <input type="button" value="登录" onclick="login();"/> <input type="reset" value="重置"/> </form> </c:if> <c:if test="${!boo}"> 登录成功<br/> 欢迎你,亲爱的${user.name} </c:if> </body></html>
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
- 39
- 40
- 41
- 42
- 43
- 44
c3p0线程池配置文件:
这个配置没啥好讲的,大家都是按这个格式来的。
注意取名,一定要取:c3p0-config.xml
否则无法读取的。
还有路径:需要在你项目的bin目录下,当然,你放src目录下也是可以的,因为myeclipse会自动把src目录下不是.java后缀的文件原样拷贝到对应的bin文件夹下面,src目录下对应的就是bin目录。
<c3p0-config> <default-config> <property name="driverClass">com.mysql.jdbc.Driver</property> <property name="jdbcUrl"> <![CDATA[jdbc:mysql://127.0.0.1:3306/hncu?useUnicode=true&characterEncoding=utf-8]]> </property> <property name="user">root</property> <property name="password">1234</property> <property name="initialPoolSize">2</property> <property name="maxIdleTime">30</property> <property name="maxPoolSize">10</property> <property name="minPoolSize">2</property> <property name="maxStatements">50</property> </default-config> </c3p0-config>
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
过滤器-实现全站编码
过滤器,很强悍的一个技术。这个必须要会。
package cn.hncu.filter;import java.io.IOException;import javax.servlet.Filter;import javax.servlet.FilterChain;import javax.servlet.FilterConfig;import javax.servlet.ServletException;import javax.servlet.ServletRequest;import javax.servlet.ServletResponse;public class CharsetFilter implements Filter{ private String charset=null; @Override public void init(FilterConfig filterConfig) throws ServletException { charset = filterConfig.getInitParameter("charset"); } @Override public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException { request.setCharacterEncoding(charset); response.setContentType("text/html;charset="+charset); chain.doFilter(request, response); } @Override public void destroy() { }}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
点击邮件激活地址后的页面:result.jsp
这个就是点击注册链接后的返回页面。
根据DAO层的不同返回值,实现了分别对用户显示不同的提示。
添加了网页自动跳转!
<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%><%@taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %><!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"><html> <head> <title>带邮箱激活的注册模块</title> <script type="text/javascript"> var tm; var i=5; function time(){ i--; div1.innerHTML = i+"秒钟以后,自动去登录!"; if(i<1){ window.clearInterval(tm); window.location.href="<c:url value='index.jsp'/>"; } } onload=function(){ tm = window.setInterval(time, 1000); }; </script> </head> <body> <c:if test="${count==-1}"> 服务器异常,请重新激活!<br/> <a href="<c:url value='/index.jsp'/>">登录</a> <br/> <div id="div1"> </div> </c:if> <c:if test="${count==0}"> 激活地址错误,请使用正确的激活地址!<br/> <a href="<c:url value='/index.jsp'/>">登录</a> <br/> <div id="div1"> </div> </c:if> <c:if test="${count==1}"> 你已经激活过,请勿重复激活!<br/> <a href="<c:url value='/index.jsp'/>">登录</a> <br/> <div id="div1"> </div> </c:if> <c:if test="${count==2}"> 激活成功,欢迎去登录!<br/> <a href="<c:url value='/index.jsp'/>">登录</a> <br/> <div id="div1"> </div> </c:if> </body></html>
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
- 39
- 40
- 41
- 42
- 43
- 44
- 45
- 46
- 47
- 48
- 49
- 50
- 51
- 52
- 53
- 54
- 55
- 56
- 57
- 58
LoginDaoJdbc-用户登录DAO实现类
这里用到了c3p0和dbutils,在query方法中,new BeanHandler<User>
(User.class) 此句可以直接给我们返回一个User对象!
package cn.hncu.login.dao;import java.sql.SQLException;import org.apache.commons.dbutils.QueryRunner;import org.apache.commons.dbutils.handlers.BeanHandler;import cn.hncu.domain.User;import cn.hncu.pubs.C3p0Pool;public class LoginDaoJdbc implements LoginDAO{ public User login(User u){ String sql = "select * from users where name=? and pwd=? and active='1' "; QueryRunner run = new QueryRunner(C3p0Pool.getDataSource()); try { User user = run.query(sql, new BeanHandler<User>(User.class) , u.getName(),u.getPwd()); return user; } catch (SQLException e) { e.printStackTrace(); return null; } }}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
还有很多代码,就不一一列出了,
项目应用MVC框架思想,注意分层。
演示结果:
激活的原理很简单,我们链接后面向我们的ActiveServlet传递了一个acode参数,用这个参数的值(UUID生成的)到后台去校验,以让用户通过验证!
完整的项目源代码链接:
https://github.com/yangchunjian/Java/tree/master/myMailWeb