【JavaMail】(2)JavaMail的一个案例:用户在网站上注册完成后给用户发一封邮件, 且需要用户通过邮件激活后才可以使用。

一、JavaMail的一个综合案例

项目要求:

用户在网站上注册完成后给用户发一封邮件。
且需要用户通过邮件激活后才可以使用。

二、关于此项目的一个整体框架设计

1、分别有以下模块:

(1)注册模块(reg)、登录模块(login)、激活模块(active)、值对象(domain)、过滤器(filter)、工具类(pubs)
(2)其中每一个模块都是采用“铁三角”模式
(3)需要用到的Jar包:

这里写图片描述

三、主页面index.jsp

<%@ 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'/>"; /* 【注意】object.action [ = sURL ] */
            document.forms[0].submit(); /*【注意】 FORM.submit() */
        }
        function login(){
            document.forms[0].action="<c:url value='/LoginServlet'/>";
            document.forms[0].submit();
        }

    </script>  
  </head>

  <body>
    <h2>用户注册</h2>
    <c:if test="${!empty error}">
        用户名或密码错误
        <c:remove var="error" scope="session"/>
    </c:if> 
    <c:if test="${sessionScope.user==null}" var="boo">
        <form action="" method="post">
            Name:<input type="text" name="name"/><br/>
            Pwd:<input type="password" name="pwd"/><br/>
            Email:<input type="text" name="email"/><br/>
            <input type="button" value="登录" onclick="login();"/>
            <input type="button" value="注册" onclick="reg();">
        </form>
    </c:if>

    <c:if test="${!boo}">
        您已经登录,用户名:${user.name}<br/>
    </c:if>
  </body>
</html>

result.jsp页面:

<%@ 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>
    <script type="text/javascript">
        /* 开始数倒计时数字 */
        var i = 4;
        function aa(){
            i--;
            div1.innerHTML=i+" 秒钟后,自动去去登录";
            if(i<1){
                /* 清除定时器 */
                window.clearInterval(tm);
                window.location.href="<c:url value='/index.jsp'/>";
            }
        }
    </script>
  </head>

  <body>
    <h2>激活结果</h2>
    <c:if test="${boo}">
        恭喜,你已经成功激活账号,请前去登录<br/>
        <a href="<c:url value='/index.jsp'/>">登录</a>
        <!-- 写一个自动登录的功能 -->
        <div id="div1">
        </div>
    </c:if>

    <script type="text/javascript">
        /* 做一个定时器 */
        tm = window.setInterval(aa, 1000);
    </script>

    <c:if test="${!boo}">
        激活不成功,请检查激活码,或另择时间再尝试!
    </c:if>

  </body>
</html>

四、注册模块(reg)

1、servlet层:RegServlet.java

package cn.hncu.reg.servlet;

import java.io.IOException;
import java.io.PrintWriter;
import java.sql.SQLException;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import cn.hncu.domain.User;
import cn.hncu.pubs.SendMailThread;
import cn.hncu.reg.service.RegService;
import cn.hncu.reg.service.RegServiceImpl;

public class RegServlet extends HttpServlet {

    private RegService service = new RegServiceImpl();
    public void doGet(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        doPost(request, response);
    }


    public void doPost(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        PrintWriter out =  response.getWriter();

        //1.收集参数
        String name = request.getParameter("name");
        String pwd = request.getParameter("pwd");
        String email = request.getParameter("email");
        //2.组织参数
        User user = new User();
        user.setName(name);
        user.setPwd(pwd);
        user.setEmail(email);
        //3.调用service层
        try {
            user = service.reg(user);
            if(user!=null){
                System.out.println("注册了一个用户:"+user);
                //【注意】如果注册成功,则给用户的邮箱 发邮件,让他到他的邮件中去激活
                new SendMailThread(user).start();
                //4.返回调用结果
                out.println("您已经成功注册了,请到邮箱中收取激活邮件,如果没有收到邮件,请再等一会儿再收!!!");
            }
        } catch (SQLException e) {
            out.println("注册失败!");
        }
    }
}

2、service层:RegService.java

package cn.hncu.reg.service;

import java.sql.SQLException;

import cn.hncu.domain.User;

public interface RegService {
    public User reg(User user) throws SQLException;
}

2、service层:RegServiceImpl.java

package cn.hncu.reg.service;

import java.sql.SQLException;

import cn.hncu.domain.User;
import cn.hncu.reg.dao.RegDAO;
import cn.hncu.reg.dao.RegDaoJdbc;

public class RegServiceImpl implements RegService{
    private RegDAO dao = new RegDaoJdbc();
    @Override
    public User reg(User user) throws SQLException {
        return dao.reg(user);
    }
}

3、dao层:RegDAO.java

package cn.hncu.reg.dao;

import java.sql.SQLException;

import cn.hncu.domain.User;

public interface RegDAO {
    public User reg(User user) throws SQLException ;
}

3、dao层:RegDaoJdbc.java

package cn.hncu.reg.dao;

import java.sql.SQLException;
import java.util.UUID;

import org.apache.commons.dbutils.QueryRunner;

import cn.hncu.domain.User;
import cn.hncu.pubs.C3p0Pool;

public class RegDaoJdbc implements RegDAO{
    @Override
    public User reg(User user) throws SQLException {
        String id = UUID.randomUUID().toString().replaceAll("-", "");
        String acode = UUID.randomUUID().toString().replaceAll("-", "");
        String sql = "insert into users(id,name,pwd,email,active,acode) values(?,?,?,?,?,?)";
        QueryRunner run = new QueryRunner(C3p0Pool.getDataSource());
        int n = run.update(sql,id,user.getName(),user.getPwd(),user.getEmail(),"0",acode);
        if(n>0){
            user.setId(id);
            user.setActive("0");
            user.setAcode(acode);
            return user;
        }
        return null;
    }

}

五、激活模块(active)

1、servlet层:ActiveServlet.java

package cn.hncu.active.servlet;

import java.io.IOException;
import java.sql.SQLException;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import cn.hncu.active.service.ActiveService;
import cn.hncu.active.service.ActiveServiceImpl;

public class ActiveServlet extends HttpServlet {

    private ActiveService service = new ActiveServiceImpl();
    public void doGet(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        doPost(request, response);
    }


    public void doPost(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        String code = request.getParameter("acode");
        boolean boo ;
        try{
            boo = service.active(code);
            //【注意】如果激活成功则将结果转发出去
            request.setAttribute("boo", boo);
        } catch (SQLException e) {
            request.setAttribute("boo", false);
        }
        request.getRequestDispatcher("jsps/result.jsp").forward(request, response);

    }

}

2、service层:ActiveService.java

package cn.hncu.active.service;

import java.sql.SQLException;

public interface ActiveService {
    public boolean active(String code)throws SQLException ;
}

2、service层:ActiveServiceImpl.java

package cn.hncu.active.service;

import java.sql.SQLException;

import cn.hncu.active.dao.ActiveDAO;
import cn.hncu.active.dao.ActiveDaoJdbc;

public class ActiveServiceImpl implements ActiveService{
    private ActiveDAO dao = new ActiveDaoJdbc();
    @Override
    public boolean active(String code) throws SQLException {
        return dao.active(code);
    }

}

3、dao层:ActiveDAO.java

package cn.hncu.active.dao;

import java.sql.SQLException;

public interface ActiveDAO {
    public boolean active(String code) throws SQLException;
}

3、dao层:ActiveDaoJdbc.java

package cn.hncu.active.dao;

import java.sql.SQLException;

import org.apache.commons.dbutils.QueryRunner;
import org.apache.commons.dbutils.handlers.ScalarHandler;

import cn.hncu.pubs.C3p0Pool;

public class ActiveDaoJdbc implements ActiveDAO{

    @Override
    public boolean active(String code) throws SQLException {
        //【注意】首先查询出是不是有激活码,传过来的激活码在数据库中是不是存在
        String sql = "select count(1) from users where acode=?";
        QueryRunner run = new  QueryRunner(C3p0Pool.getDataSource());
        int count = Integer.parseInt(run.query(sql, new ScalarHandler(), code)+"");
        if(count==0){
            return false;//【注意】此时激活码错误
        }else{
            //【注意】否则激活码存在的话,将激活码销毁,激活状态以激活
            //【注意】单词写对,坑了一把
            sql = "update users set active='1',acode='' where acode=?";
            run.update(sql, code);
            return true;
        }
    }
}

六、登录模块(login)

1、servlet层:LoginServlet.java

package cn.hncu.login.servlet;

import java.io.IOException;
import java.sql.SQLException;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import cn.hncu.domain.User;
import cn.hncu.login.service.LoginService;
import cn.hncu.login.service.LoginServiceImpl;

public class LoginServlet extends HttpServlet {

    private LoginService service = new LoginServiceImpl();
    public void doGet(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        doPost(request, response);
    }


    public void doPost(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        //1.收集参数
        String name = request.getParameter("name");
        String pwd = request.getParameter("pwd");
        //2.组织参数
        User user = new User();
        user.setName(name);
        user.setPwd(pwd);
        //3.调用service层
        try {
            user= service.login(user);
            if(user==null){
                request.setAttribute("error", "1");//【注意】如果返回user为空则表示登录的用户未激活
            }else{
                request.getSession().setAttribute("user", user);
            }
        } catch (SQLException e) {
            request.setAttribute("error", "1");//【注意】如果返回user为空则表示登录的用户未激活
        }
        //4.返回结果页面
        response.sendRedirect(request.getContextPath()+"/index.jsp");
    }
}

2、service层:LoginService.java

package cn.hncu.login.service;

import java.sql.SQLException;

import cn.hncu.domain.User;

public interface LoginService {
    public User login(User user)throws SQLException ;
}

2、service层:LoginServiceImpl.java

package cn.hncu.login.service;

import java.sql.SQLException;

import cn.hncu.domain.User;
import cn.hncu.login.dao.LoginDAO;
import cn.hncu.login.dao.LoginDaoJdbc;

public class LoginServiceImpl implements LoginService{
    private LoginDAO dao = new LoginDaoJdbc();
    @Override
    public User login(User user) throws SQLException {
        return dao.login(user);
    }
}

3、dao层:LoginDAO.java

package cn.hncu.login.dao;

import java.sql.SQLException;

import cn.hncu.domain.User;

public interface LoginDAO {
    public User login(User user)throws SQLException;
}

3、dao层:LoginDaoJdbc.java

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{
    @Override
    public User login(User user) throws SQLException {
        String sql = "select * from users where name=? and pwd=? and active='1'";
        QueryRunner run = new QueryRunner(C3p0Pool.getDataSource());
        user = run.query(sql, new BeanHandler<User>(User.class), user.getName(),user.getPwd());
        return user;
    }
}

七、工具包(pubs)

1、C3p0Pool.java工具类:

package cn.hncu.pubs;

import java.sql.Connection;
import java.sql.SQLException;

import javax.sql.DataSource;

import com.mchange.v2.c3p0.ComboPooledDataSource;
/※※※以后我们开发可以做一个这样的池来使用
public class C3p0Pool {
    private static DataSource ds; //单例的池
    private static ThreadLocal<Connection> t = new ThreadLocal<Connection>();

    static{
        try {
            ds = new ComboPooledDataSource();
        } catch (Exception e) {
            throw new RuntimeException("数据库连接池创建失败!", e);
        }
    }

    //以后会用到这个功能 
    public static DataSource getDataSource(){
        return ds;
    }

    public static Connection getConn() throws SQLException{
        Connection con = t.get();
        if(con==null){
            con = ds.getConnection();
            t.set(con);
        }
        return con;
    }

    public static void clearConFromThreadLocal(){
        t.set(null);
    }
}

2、c3p0-config.xml:

<c3p0-config>
    <default-config>
        <property name="driverClass">com.mysql.jdbc.Driver</property>
        <property name="jdbcUrl">
            <![CDATA[jdbc:mysql://127.0.0.1:3306/abc?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> 

3、发送邮件工具类:SendMailThread.java:

package cn.hncu.pubs;

import java.util.Date;
import java.util.Properties;

import javax.mail.Authenticator;
import javax.mail.PasswordAuthentication;
import javax.mail.Session;
import javax.mail.Transport;
import javax.mail.internet.InternetAddress;
import javax.mail.internet.MimeMessage;
import javax.mail.internet.MimeMessage.RecipientType;

import cn.hncu.domain.User;

public class SendMailThread extends Thread{
    private User user;
    public SendMailThread(User user) {
        this.user = user;
    }

    @Override
    public void run() {
        try {
            //【注意】开始发邮件
            Properties p = new  Properties();
            p.setProperty("mail.host", "smtp.sina.com");
            p.setProperty("mail.smtp.auth", "true");//认证登录
            Session session = Session.getDefaultInstance(p, new Authenticator() {
                @Override
                protected PasswordAuthentication getPasswordAuthentication() {
                    return new PasswordAuthentication("hncujava", "hncu1234567");
                }
            });
            session.setDebug(true);//【注意】以debug方式 应答,进行通讯

            //【注意】准备邮件
            MimeMessage msg = new MimeMessage(session);//从session中创建邮件
            msg.setFrom(new InternetAddress("hncujava@sina.com"));
            msg.setRecipient(RecipientType.TO, new InternetAddress(user.getEmail()));
            msg.setSubject("账号激活邮件,城院公司欢迎你");
            String info="激活:<a href='http://127.0.0.1:8080/mailWeb1602Test/ActiveServlet?acode="+user.getAcode()+"'>激活</a>";
            info = info + "<br/>如果激活未成功,请把地址复制到浏览器进行手动请求以激活:http://127.0.0.1:8080/mailWeb1602Test/ActiveServlet?acode="+user.getAcode();
            msg.setContent(info,"text/html;charset=utf-8");
            msg.setSentDate(new Date());

            //【注意】发送邮件
            Transport.send(msg);
        }  catch (Exception e) {
            e.printStackTrace();
        }
    }
}

八、值对象层(domain)

1、user.java

package cn.hncu.domain;

/**
 * private String id;//ID
    private String name;//用户名
    private String pwd;//密码
    private String email;//Email
    private String active;//激活状态
    private String acode;//激活码
 * @author user
 *
 */
public class User {
    private String id;//ID
    private String name;//用户名
    private String pwd;//密码
    private String email;//Email
    private String active;//激活状态
    private String acode;//激活码
    public User() {
        super();
    }
    public String getId() {
        return id;
    }
    public void setId(String id) {
        this.id = id;
    }
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    public String getPwd() {
        return pwd;
    }
    public void setPwd(String pwd) {
        this.pwd = pwd;
    }
    public String getEmail() {
        return email;
    }
    public void setEmail(String email) {
        this.email = email;
    }
    public String getActive() {
        return active;
    }
    public void setActive(String active) {
        this.active = active;
    }
    public String getAcode() {
        return acode;
    }
    public void setAcode(String acode) {
        this.acode = acode;
    }
    @Override
    public String toString() {
        return "User [id=" + id + ", name=" + name + ", pwd=" + pwd
                + ", email=" + email + ", active=" + active + ", acode="
                + acode + "]";
    }
}

九、预处理过滤器(PreFilter)

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 PreFilter implements Filter{

    @Override
    public void init(FilterConfig filterConfig) throws ServletException {
    }

    @Override
    public void doFilter(ServletRequest request, ServletResponse response,
            FilterChain chain) throws IOException, ServletException {
        request.setCharacterEncoding("utf-8");
        response.setContentType("text/html;charset=utf-8");
        chain.doFilter(request, response);
    }

    @Override
    public void destroy() {
    }

}

十、web.xml配置文件

<?xml version="1.0" encoding="UTF-8"?>
<web-app version="3.0" 
    xmlns="http://java.sun.com/xml/ns/javaee" 
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
    xsi:schemaLocation="http://java.sun.com/xml/ns/javaee 
    http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd">
  <display-name></display-name>
  <servlet>
    <servlet-name>RegServlet</servlet-name>
    <servlet-class>cn.hncu.reg.servlet.RegServlet</servlet-class>
  </servlet>
  <servlet>
    <servlet-name>ActiveServlet</servlet-name>
    <servlet-class>cn.hncu.active.servlet.ActiveServlet</servlet-class>
  </servlet>
  <servlet>
    <servlet-name>LoginServlet</servlet-name>
    <servlet-class>cn.hncu.login.servlet.LoginServlet</servlet-class>
  </servlet>


  <filter>
    <filter-name>PreFilter</filter-name>
    <filter-class>cn.hncu.filter.PreFilter</filter-class>
  </filter>



  <servlet-mapping>
    <servlet-name>RegServlet</servlet-name>
    <url-pattern>/RegServlet</url-pattern>
  </servlet-mapping>
  <servlet-mapping>
    <servlet-name>ActiveServlet</servlet-name>
    <url-pattern>/ActiveServlet</url-pattern>
  </servlet-mapping>
  <servlet-mapping>
    <servlet-name>LoginServlet</servlet-name>
    <url-pattern>/LoginServlet</url-pattern>
  </servlet-mapping>
  <filter-mapping>
    <filter-name>PreFilter</filter-name>
    <url-pattern>/RegServlet</url-pattern>
    <url-pattern>/LoginServlet</url-pattern>
  </filter-mapping> 
  <welcome-file-list>
    <welcome-file>index.jsp</welcome-file>
  </welcome-file-list>
</web-app>

十一、项目执行效果:

1、首页:

这里写图片描述

2、填写注册信息:

这里写图片描述

3、跳转到注册成功页面:

这里写图片描述

4、数据库收到注册信息:

这里写图片描述

acode码末尾四位为:f32e

5、注册邮箱收到邮件:

这里写图片描述
这里写图片描述

收到的邮件中连接的acode码末尾四位为:f32e

6、点击激活:

这里写图片描述

激活成功的超链接中的acode码末尾四位为:f32e

7、此时刷新数据库,发现acode码被清空,激活状态变为1:

这里写图片描述

8、用注册的用户名和密码登录:

这里写图片描述
这里写图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值