JavaWeb综合案例第一天(注册_验证码_邮箱验证_登录_退出_登陆成功之后的信息展示)

一、搭建开发环境—基于前后端分离的旅游项目

项目需要用到的技术栈

后端:Servlet, beanUtils , Jackson , javaMail , jdbctemplate ,druid + mysql
前端:bootstrap + jquery

1.创建web项目,创建java目录和resources目录
JavaWeb综合案例第一天(注册_验证码_邮箱验证_登录_退出_登陆成功之后的信息展示)_第1张图片
2.在pom.xml中导入项目需要用的依赖包




  4.0.0

  com.bianyiit
  maven_tourism
  1.0-SNAPSHOT
  war

  maven_tourism Maven Webapp
  
  http://www.example.com

  
    UTF-8
    1.8
    1.8
  

  

    
    
      com.fasterxml.jackson.core
      jackson-core
      2.9.0
    
    
      com.fasterxml.jackson.core
      jackson-databind
      2.9.0
    
    
      com.fasterxml.jackson.core
      jackson-annotations
      2.9.0
    

    
    
      redis.clients
      jedis
      2.7.2
    

    
    
      commons-beanutils
      commons-beanutils
      1.9.2
      compile
    
    
      commons-logging
      commons-logging
      1.1.1
      compile
    

    
    
      javax.mail
      javax.mail-api
      1.5.6
    
    
      com.sun.mail
      javax.mail
      1.5.3
    
    
    
      redis.clients
      jedis
      2.7.0
    

    
    
      org.springframework
      spring-jdbc
      5.0.5.RELEASE
    
    
      org.springframework
      spring-tx
      5.0.5.RELEASE
    
    
      org.springframework
      spring-context
      5.0.5.RELEASE
    

    
    
      com.alibaba
      druid
      1.1.10
    

    
    
      mysql
      mysql-connector-java
      5.1.6
    


    
    
      javax.servlet
      javax.servlet-api
      3.1.0
      provided
    
    
      javax.servlet
      jsp-api
      2.0
      provided
    


    
    
      junit
      junit
      4.11
      test
    
  

  
    day12_redis_role
    
      
        org.apache.tomcat.maven
        tomcat7-maven-plugin
        2.2
        
          
          8080
          
          /
        
      
    
  

3.在webapp下导入项目的前端资源--各类html页面/img/css/jquery/bootstrap...
JavaWeb综合案例第一天(注册_验证码_邮箱验证_登录_退出_登陆成功之后的信息展示)_第2张图片
4.创建数据库,导入六张表
JavaWeb综合案例第一天(注册_验证码_邮箱验证_登录_退出_登陆成功之后的信息展示)_第3张图片
5.在resources中导入两个配置文件
JavaWeb综合案例第一天(注册_验证码_邮箱验证_登录_退出_登陆成功之后的信息展示)_第4张图片
JavaWeb综合案例第一天(注册_验证码_邮箱验证_登录_退出_登陆成功之后的信息展示)_第5张图片
6.在util包下导入五个工具类
JavaWeb综合案例第一天(注册_验证码_邮箱验证_登录_退出_登陆成功之后的信息展示)_第6张图片

package com.bianyiit.util;

import com.alibaba.druid.pool.DruidDataSourceFactory;

import javax.sql.DataSource;
import java.io.IOException;
import java.io.InputStream;
import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.Properties;

/*
	1. 声明静态数据源成员变量
	2. 创建连接池对象
	3. 定义公有的得到数据源的方法
	4. 定义得到连接对象的方法
	5. 定义关闭资源的方法
 */
public class JDBCUtils {
	// 1.	声明静态数据源成员变量
	private static DataSource ds;

	// 2. 创建连接池对象
	static {
		// 加载配置文件中的数据
		InputStream is = JDBCUtils.class.getClassLoader().getResourceAsStream("druid.properties");
		Properties pp = new Properties();
		try {
			pp.load(is);
			// 创建连接池,使用配置文件中的参数
			ds = DruidDataSourceFactory.createDataSource(pp);
		} catch (IOException e) {
			e.printStackTrace();
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

	// 3. 定义公有的得到数据源的方法
	public static DataSource getDataSource() {
		return ds;
	}

	// 4. 定义得到连接对象的方法
	public static Connection getConnection() throws SQLException {
		return ds.getConnection();
	}

	// 5.定义关闭资源的方法
	public static void close(Connection conn, Statement stmt, ResultSet rs) {
		if (rs != null) {
			try {
				rs.close();
			} catch (SQLException e) {}
		}

		if (stmt != null) {
			try {
				stmt.close();
			} catch (SQLException e) {}
		}

		if (conn != null) {
			try {
				conn.close();
			} catch (SQLException e) {}
		}
	}

	// 6.重载关闭方法
	public static void close(Connection conn, Statement stmt) {
		close(conn, stmt, null);
	}
}
package com.bianyiit.util;

import redis.clients.jedis.Jedis;
import redis.clients.jedis.JedisPool;
import redis.clients.jedis.JedisPoolConfig;

import java.io.IOException;
import java.io.InputStream;
import java.util.Properties;

/**
 * Jedis工具类
 */
public final class JedisUtil {
    private static JedisPool jedisPool;

    static {
        //读取配置文件
        InputStream is = JedisPool.class.getClassLoader().getResourceAsStream("jedis.properties");
        //创建Properties对象
        Properties pro = new Properties();
        //关联文件
        try {
            pro.load(is);
        } catch (IOException e) {
            e.printStackTrace();
        }
        //获取数据,设置到JedisPoolConfig中
        JedisPoolConfig config = new JedisPoolConfig();
        config.setMaxTotal(Integer.parseInt(pro.getProperty("maxTotal")));
        config.setMaxIdle(Integer.parseInt(pro.getProperty("maxIdle")));

        //初始化JedisPool
        jedisPool = new JedisPool(config, pro.getProperty("host"), Integer.parseInt(pro.getProperty("port")));


    }

    /**
     * 获取连接方法
     */
    public static Jedis getJedis() {
        return jedisPool.getResource();
    }

    /**
     * 关闭Jedis
     */
    public static void close(Jedis jedis) {
        if (jedis != null) {
            jedis.close();
        }
    }
}
package com.bianyiit.util;

import javax.mail.*;
import javax.mail.internet.InternetAddress;
import javax.mail.internet.MimeMessage;
import java.util.Properties;

/**
 * 发邮件工具类
 */
public final class MailUtils {
    private static final String USER = "[email protected]"; // 发件人称号,同邮箱地址
    private static final String PASSWORD = "xxxxx"; // 如果是qq邮箱可以使户端授权码,或者登录密码

    /**
     *
     * @param to 收件人邮箱
     * @param text 邮件正文
     * @param title 标题
     */
    /* 发送验证信息的邮件 */
    public static boolean sendMail(String to, String text, String title){
        try {
            final Properties props = new Properties();
            props.put("mail.smtp.auth", "true");
            props.put("mail.smtp.host", "smtp.163.com");

            // 发件人的账号
            props.put("mail.user", USER);
            //发件人的密码
            props.put("mail.password", PASSWORD);

            // 构建授权信息,用于进行SMTP进行身份验证
            Authenticator authenticator = new Authenticator() {
                @Override
                protected PasswordAuthentication getPasswordAuthentication() {
                    // 用户名、密码
                    String userName = props.getProperty("mail.user");
                    String password = props.getProperty("mail.password");
                    return new PasswordAuthentication(userName, password);
                }
            };
            // 使用环境属性和授权信息,创建邮件会话
            Session mailSession = Session.getInstance(props, authenticator);
            // 创建邮件消息
            MimeMessage message = new MimeMessage(mailSession);
            // 设置发件人
            String username = props.getProperty("mail.user");
            InternetAddress form = new InternetAddress(username);
            message.setFrom(form);

            // 设置收件人
            InternetAddress toAddress = new InternetAddress(to);
            message.setRecipient(Message.RecipientType.TO, toAddress);

            // 设置邮件标题
            message.setSubject(title);

            // 设置邮件的内容体
            message.setContent(text, "text/html;charset=UTF-8");
            // 发送邮件
            Transport.send(message);
            return true;
        }catch (Exception e){
            e.printStackTrace();
        }
        return false;
    }

    public static void main(String[] args) throws Exception { // 做测试用
        MailUtils.sendMail("[email protected]","你好,这是一封来自编易官方的邮件。","测试邮件");
        System.out.println("发送成功");
    }
}
package com.bianyiit.util;

import java.security.MessageDigest;

/**
 * 写一个MD5算法,运行结果与MySQL的md5()函数相同
 * 将明文密码转成MD5密码
 * 123456->e10adc3949ba59abbe56e057f20f883e
 */
public final class Md5Util {
	private Md5Util(){}
	/**
	 * 将明文密码转成MD5密码 
	 */
	public static String encodeByMd5(String password) throws Exception{
		//Java中MessageDigest类封装了MD5和SHA算法,今天我们只要MD5算法
		MessageDigest md5 = MessageDigest.getInstance("MD5");
		//调用MD5算法,即返回16个byte类型的值
		byte[] byteArray = md5.digest(password.getBytes());
		//注意:MessageDigest只能将String转成byte[],接下来的事情,由我们程序员来完成
		return byteArrayToHexString(byteArray);
	}
	/**
	 * 将byte[]转在16进制字符串 
	 */
	private static String byteArrayToHexString(byte[] byteArray) {
		StringBuffer sb = new StringBuffer();
		//遍历
		for(byte b : byteArray){//16次
			//取出每一个byte类型,进行转换
			String hex = byteToHexString(b);
			//将转换后的值放入StringBuffer中
			sb.append(hex);
		}
		return sb.toString();
	}
	/**
	 * 将byte转在16进制字符串 
	 */
	private static String byteToHexString(byte b) {//-31转成e1,10转成0a,。。。
		//将byte类型赋给int类型
		int n = b;
		//如果n是负数
		if(n < 0){
			//转正数
			//-31的16进制数,等价于求225的16进制数 
			n = 256 + n;
		}
		//商(14),数组的下标
		int d1 = n / 16;
		//余(1),数组的下标
		int d2 = n % 16;
		//通过下标取值
		return hex[d1] + hex[d2];
	}
	private static String[] hex = {"0","1","2","3","4","5","6","7","8","9","a","b","c","d","e","f"};
	/**
	 * 测试
	 */
	public static void main(String[] args) throws Exception{
		String password = "123456";
		String passwordMD5 = Md5Util.encodeByMd5(password);
		System.out.println(password);
		System.out.println(passwordMD5);
	}
}
package com.bianyiit.util;

import java.util.UUID;

/**
 * 产生UUID随机字符串工具类
 */
public final class UuidUtil {
	private UuidUtil(){}
	public static String getUuid(){
		return UUID.randomUUID().toString().replace("-","");
	}
	/**
	 * 测试
	 */
	public static void main(String[] args) {
		System.out.println(UuidUtil.getUuid());
		System.out.println(UuidUtil.getUuid());
		System.out.println(UuidUtil.getUuid());
		System.out.println(UuidUtil.getUuid());
	}
}

7.在domain下新建两个实体类

package com.bianyiit.domain;

import java.io.Serializable;

/**
 * 用户实体类
 */
public class User implements Serializable {
    private int uid;//用户id
    private String username;//用户名,账号
    private String password;//密码
    private String name;//真实姓名
    private String birthday;//出生日期
    private String sex;//男或女
    private String telephone;//手机号
    private String email;//邮箱
    private String status;//激活状态,Y代表激活,N代表未激活
    private String code;//激活码(要求唯一)

    /**
     * 无参构造方法
     */
    public User() {
    }

    /**
     * 有参构方法
     * @param uid
     * @param username
     * @param password
     * @param name
     * @param birthday
     * @param sex
     * @param telephone
     * @param email
     * @param status
     * @param code
     */
    public User(int uid, String username, String password, String name, String birthday, String sex, String telephone, String email, String status, String code) {
        this.uid = uid;
        this.username = username;
        this.password = password;
        this.name = name;
        this.birthday = birthday;
        this.sex = sex;
        this.telephone = telephone;
        this.email = email;
        this.status = status;
        this.code = code;
    }

    public int getUid() {
        return uid;
    }

    public void setUid(int uid) {
        this.uid = uid;
    }

    public String getUsername() {
        return username;
    }

    public void setUsername(String username) {
        this.username = username;
    }

    public String getPassword() {
        return password;
    }

    public void setPassword(String password) {
        this.password = password;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getBirthday() {
        return birthday;
    }

    public void setBirthday(String birthday) {
        this.birthday = birthday;
    }

    public String getSex() {
        return sex;
    }

    public void setSex(String sex) {
        this.sex = sex;
    }

    public String getTelephone() {
        return telephone;
    }

    public void setTelephone(String telephone) {
        this.telephone = telephone;
    }

    public String getEmail() {
        return email;
    }

    public void setEmail(String email) {
        this.email = email;
    }

    public String getStatus() {
        return status;
    }

    public void setStatus(String status) {
        this.status = status;
    }

    public String getCode() {
        return code;
    }

    public void setCode(String code) {
        this.code = code;
    }

    @Override
    public String toString() {
        return "User{" +
                "uid=" + uid +
                ", username='" + username + '\'' +
                ", password='" + password + '\'' +
                ", name='" + name + '\'' +
                ", birthday='" + birthday + '\'' +
                ", sex='" + sex + '\'' +
                ", telephone='" + telephone + '\'' +
                ", email='" + email + '\'' +
                ", status='" + status + '\'' +
                ", code='" + code + '\'' +
                '}';
    }
}
package com.bianyiit.domain;

import java.io.Serializable;
import java.util.Objects;

/**
 * 用于封装后端返回前端数据对象
 */
public class ResultInfo implements Serializable {
    private boolean flag;//后端返回结果正常为true,发生异常返回false
    private Object data;//后端返回结果数据对象
    private String errorMsg;//发生异常的错误消息

    //无参构造方法
    public ResultInfo() {
    }
    public ResultInfo(boolean flag) {
        this.flag = flag;
    }
    /**
     * 有参构造方法
     * @param flag
     * @param errorMsg
     */
    public ResultInfo(boolean flag, String errorMsg) {
        this.flag = flag;
        this.errorMsg = errorMsg;
    }
    /**
     * 有参构造方法
     * @param flag
     * @param data
     * @param errorMsg
     */
    public ResultInfo(boolean flag, Object data, String errorMsg) {
        this.flag = flag;
        this.data = data;
        this.errorMsg = errorMsg;
    }

    public boolean isFlag() {
        return flag;
    }

    public void setFlag(boolean flag) {
        this.flag = flag;
    }

    public Object getData() {
        return data;
    }

    public void setData(Object data) {
        this.data = data;
    }

    public String getErrorMsg() {
        return errorMsg;
    }

    public void setErrorMsg(String errorMsg) {
        this.errorMsg = errorMsg;
    }
}

二、注册功能的分析与代码编写

1.先打开index.html,查看整个网站的门户页面

2.打开register.html,进行用户名,密码的前端校验



    
        
        注册
        
        
		
		
		


    
	
	
	
        
    	

新用户注册

USER REGISTER

已有账号? 立即登录

1.点击注册按钮,进入注册界面
JavaWeb综合案例第一天(注册_验证码_邮箱验证_登录_退出_登陆成功之后的信息展示)_第7张图片
2.前端校验的时机一:输入框失去焦点
JavaWeb综合案例第一天(注册_验证码_邮箱验证_登录_退出_登陆成功之后的信息展示)_第8张图片
2.前端校验的时机二:提交表单之前
JavaWeb综合案例第一天(注册_验证码_邮箱验证_登录_退出_登陆成功之后的信息展示)_第9张图片
4.用户名错误,密码正确的效果演示(不涉及服务器的处理,单纯的前端校验)

5.用户名正确,密码错误的效果演示(不涉及服务器的处理,单纯的前端校验)

3.在web下新建一个filter包,用于对浏览器传入的request进行中文乱码的解决

package com.bianyiit.web.filter;

import javax.servlet.*;
import javax.servlet.annotation.WebFilter;
import java.io.IOException;

@WebFilter("/*")
public class CharacterEncodingFilter implements Filter {

    public void doFilter(ServletRequest req, ServletResponse resp, FilterChain chain) throws ServletException, IOException {
        req.setCharacterEncoding("utf-8");
        chain.doFilter(req, resp);
    }

    public void init(FilterConfig config) throws ServletException {

    }

    public void destroy() {
    }
}

3.在web下新建一个servlet包,在这个包下新建一个RegistServlet

package com.bianyiit.web.servlet;

import com.bianyiit.domain.ResultInfo;
import com.bianyiit.domain.User;
import com.bianyiit.services.UserService;
import com.bianyiit.services.UserServiceImpl;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.apache.commons.beanutils.BeanUtils;

import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.Map;

@WebServlet("/registServlet")
public class RegistServlet extends HttpServlet {
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        response.setContentType("application/json;charset=utf-8");
        ResultInfo resultInfo = new ResultInfo();

        String check = request.getParameter("check");
        String checkcode_server = (String) request.getSession().getAttribute("CHECKCODE_SERVER");
        request.getSession().removeAttribute("CHECKCODE_SERVER");

        ObjectMapper objectMapper = new ObjectMapper();
        if(checkcode_server==null||!check.equalsIgnoreCase(checkcode_server)){
            resultInfo.setFlag(false);
            resultInfo.setErrorMsg("验证码不正确");
            objectMapper.writeValue(response.getWriter(),resultInfo);
        }
        Map parameterMap = request.getParameterMap();
        User user=new User();
        try {
            BeanUtils.populate(user,parameterMap);
        } catch (Exception e) {
            e.printStackTrace();
        }
        //System.out.println(user);
        UserService userService = new UserServiceImpl();
        int update = 0;
        try {
            update = userService.regist(user);
        } catch (Exception e) {
            e.printStackTrace();
            resultInfo.setFlag(false);
            resultInfo.setErrorMsg("注册失败");
            objectMapper.writeValue(response.getWriter(),resultInfo);
            return;
        }
        if(update>0){
            //response.sendRedirect(request.getContextPath()+"/register.html");
            resultInfo.setFlag(true);
            resultInfo.setErrorMsg("注册成功");
            objectMapper.writeValue(response.getWriter(),resultInfo);
        }
    }

    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        doPost(request, response);
    }
}

业务处理流程
JavaWeb综合案例第一天(注册_验证码_邮箱验证_登录_退出_登陆成功之后的信息展示)_第10张图片
4.采用面向接口编程,能够提高程序的可维护型和可扩展性
JavaWeb综合案例第一天(注册_验证码_邮箱验证_登录_退出_登陆成功之后的信息展示)_第11张图片

package com.bianyiit.services;

import com.bianyiit.domain.User;

public interface UserService {
    int regist(User user);
}
package com.bianyiit.services;

import com.bianyiit.dao.UserDao;
import com.bianyiit.dao.UserDaoImpl;
import com.bianyiit.domain.User;
import com.bianyiit.util.JedisUtil;
import com.bianyiit.util.MailUtils;
import com.bianyiit.util.UuidUtil;
import redis.clients.jedis.Jedis;

public class UserServiceImpl implements UserService {
    UserDao userDao=new UserDaoImpl();
    @Override
    public int regist(User user) {
        //1.保存用户到数据库
        int add = userDao.add(user);
        return add;
    }
}
package com.bianyiit.dao;

import com.bianyiit.domain.User;

public interface UserDao {
    int add(User user);
}
package com.bianyiit.dao;

import com.bianyiit.domain.User;
import com.bianyiit.util.JDBCUtils;
import org.springframework.dao.DataAccessException;
import org.springframework.jdbc.core.BeanPropertyRowMapper;
import org.springframework.jdbc.core.JdbcTemplate;

public class UserDaoImpl implements UserDao{
    JdbcTemplate jdbcTemplate = new JdbcTemplate(JDBCUtils.getDataSource());
    @Override
    public int add(User user) {
        String sql="insert into tab_user values (null,?,?,?,?,?,?,?,?,?)";
        int update = jdbcTemplate.update(sql,
                user.getUsername(),
                user.getPassword(),
                user.getName(),
                user.getBirthday(),
                user.getSex(),
                user.getTelephone(),
                user.getEmail(),
                user.getStatus(),
                user.getCode());
        return update;
    }
}

页面效果展示
JavaWeb综合案例第一天(注册_验证码_邮箱验证_登录_退出_登陆成功之后的信息展示)_第12张图片
JavaWeb综合案例第一天(注册_验证码_邮箱验证_登录_退出_登陆成功之后的信息展示)_第13张图片

三、验证码功能的分析与代码编写

1.找到register页面
JavaWeb综合案例第一天(注册_验证码_邮箱验证_登录_退出_登陆成功之后的信息展示)_第14张图片
2.在servlet中新建一个CheckCodeServlet

package com.bianyiit.web.servlet;

import javax.imageio.ImageIO;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.IOException;
import java.util.Random;

/**
 * 验证码
 */
@WebServlet("/checkCode")
public class CheckCodeServlet extends HttpServlet {
	public void doGet(HttpServletRequest request, HttpServletResponse response)throws ServletException, IOException {
		
		//服务器通知浏览器不要缓存
		response.setHeader("pragma","no-cache");
		response.setHeader("cache-control","no-cache");
		response.setHeader("expires","0");
		
		//在内存中创建一个长80,宽30的图片,默认黑色背景
		//参数一:长
		//参数二:宽
		//参数三:颜色
		int width = 80;
		int height = 30;
		BufferedImage image = new BufferedImage(width,height,BufferedImage.TYPE_INT_RGB);
		
		//获取画笔
		Graphics g = image.getGraphics();
		//设置画笔颜色为灰色
		g.setColor(Color.GRAY);
		//填充图片
		g.fillRect(0,0, width,height);
		
		//产生4个随机验证码,12Ey
		String checkCode = getCheckCode();
		//将验证码放入HttpSession中
		request.getSession().setAttribute("CHECKCODE_SERVER",checkCode);
		
		//设置画笔颜色为黄色
		g.setColor(Color.YELLOW);
		//设置字体的小大
		g.setFont(new Font("黑体",Font.BOLD,24));
		//向图片上写入验证码
		g.drawString(checkCode,15,25);
		
		//将内存中的图片输出到浏览器
		//参数一:图片对象
		//参数二:图片的格式,如PNG,JPG,GIF
		//参数三:图片输出到哪里去
		ImageIO.write(image,"PNG",response.getOutputStream());
	}
	/**
	 * 产生4位随机字符串 
	 */
	private String getCheckCode() {
		String base = "0123456789ABCDEFGabcdefg";
		int size = base.length();
		Random r = new Random();
		StringBuffer sb = new StringBuffer();
		for(int i=1;i<=4;i++){
			//产生0到size-1的随机值
			int index = r.nextInt(size);
			//在base字符串中获取下标为index的字符
			char c = base.charAt(index);
			//将c放入到StringBuffer中去
			sb.append(c);
		}
		return sb.toString();
	}
	public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		this.doGet(request,response);
	}
}

验证码效果演示:

四、邮箱验证功能的分析与代码编写

1.回到注册用到的UserServiceImpl,当我们将用户信息保存到数据库之后,发送激活邮箱到真实的邮箱了

package com.bianyiit.services;

import com.bianyiit.dao.UserDao;
import com.bianyiit.dao.UserDaoImpl;
import com.bianyiit.domain.User;
import com.bianyiit.util.JedisUtil;
import com.bianyiit.util.MailUtils;
import com.bianyiit.util.UuidUtil;
import redis.clients.jedis.Jedis;

public class UserServiceImpl implements UserService {
    UserDao userDao=new UserDaoImpl();
    @Override
    public int regist(User user) {
        //1.保存用户到数据库
        int add = userDao.add(user);
        //2.发送激活邮件
        String uuid = UuidUtil.getUuid();
        Jedis jedis = JedisUtil.getJedis();
        //两小时验证码有效
        jedis.setex(uuid,5*60,user.getUsername());
        jedis.close();

        String mailContent="请点此激活您的用户";
        MailUtils.sendMail(user.getEmail(),mailContent,"用户激活邮件");
        return add;
    }

    @Override
    public boolean active(String activeCode) {

        Jedis jedis = JedisUtil.getJedis();
        String username = jedis.get(activeCode);
        if(username==null||username.length()==0){
            return false;
        }else {
            int active = userDao.active(username);
            if(active>0){
                return true;
            }else{
                return false;
            }
        }
    }
}

2.使用一个MailUtil工具类去完成这个发送邮箱的封装

package com.bianyiit.util;

import javax.mail.*;
import javax.mail.internet.InternetAddress;
import javax.mail.internet.MimeMessage;
import java.util.Properties;

/**
 * 发邮件工具类
 */
public final class MailUtils {
    private static final String USER = "[email protected]"; // 发件人称号,同邮箱地址
    private static final String PASSWORD = "1f5ewf1a5f1ae5fa"; // 如果是qq邮箱可以使户端授权码,或者登录密码

    /**
     *
     * @param to 收件人邮箱
     * @param text 邮件正文
     * @param title 标题
     */
    /* 发送验证信息的邮件 */
    public static boolean sendMail(String to, String text, String title){
        try {
            final Properties props = new Properties();
            props.put("mail.smtp.auth", "true");
            props.put("mail.smtp.host", "smtp.qq.com");

            // 发件人的账号
            props.put("mail.user", USER);
            //发件人的密码
            props.put("mail.password", PASSWORD);

            // 构建授权信息,用于进行SMTP进行身份验证
            Authenticator authenticator = new Authenticator() {
                @Override
                protected PasswordAuthentication getPasswordAuthentication() {
                    // 用户名、密码
                    String userName = props.getProperty("mail.user");
                    String password = props.getProperty("mail.password");
                    return new PasswordAuthentication(userName, password);
                }
            };
            // 使用环境属性和授权信息,创建邮件会话
            Session mailSession = Session.getInstance(props, authenticator);
            // 创建邮件消息
            MimeMessage message = new MimeMessage(mailSession);
            // 设置发件人
            String username = props.getProperty("mail.user");
            InternetAddress form = new InternetAddress(username);
            message.setFrom(form);

            // 设置收件人
            InternetAddress toAddress = new InternetAddress(to);
            message.setRecipient(Message.RecipientType.TO, toAddress);

            // 设置邮件标题
            message.setSubject(title);

            // 设置邮件的内容体
            message.setContent(text, "text/html;charset=UTF-8");
            // 发送邮件
            Transport.send(message);
            return true;
        }catch (Exception e){
            e.printStackTrace();
        }
        return false;
    }

    public static void main(String[] args) throws Exception { // 做测试用
        MailUtils.sendMail("[email protected]","你好,这是一封来自编易官方的邮件。","测试邮件");
        System.out.println("发送成功");
    }
}

3.去QQ邮箱中开启SMTP和POP3协议
JavaWeb综合案例第一天(注册_验证码_邮箱验证_登录_退出_登陆成功之后的信息展示)_第15张图片
4.开启成功之后,通过如下代码向用户发送邮件
JavaWeb综合案例第一天(注册_验证码_邮箱验证_登录_退出_登陆成功之后的信息展示)_第16张图片
JavaWeb综合案例第一天(注册_验证码_邮箱验证_登录_退出_登陆成功之后的信息展示)_第17张图片
JavaWeb综合案例第一天(注册_验证码_邮箱验证_登录_退出_登陆成功之后的信息展示)_第18张图片
5.进入邮箱点击之后,跳转至ActiveServlet
JavaWeb综合案例第一天(注册_验证码_邮箱验证_登录_退出_登陆成功之后的信息展示)_第19张图片

package com.bianyiit.web.servlet;

import com.bianyiit.services.UserService;
import com.bianyiit.services.UserServiceImpl;

import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

@WebServlet("/activeServlet")
public class ActiveServlet extends HttpServlet {
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        String activeCode = request.getParameter("activeCode");
        System.out.println(activeCode);
        UserService userService=new UserServiceImpl();
        boolean isactive = userService.active(activeCode);
        if(isactive){
            //激活成功,跳转至主页
            response.sendRedirect(request.getContextPath()+"/active_ok.html");
        }else {
            response.sendRedirect(request.getContextPath()+"/active_fail.html");
        }
    }

    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        doPost(request, response);
    }
}

JavaWeb综合案例第一天(注册_验证码_邮箱验证_登录_退出_登陆成功之后的信息展示)_第20张图片
激活成功之后的效果演示
JavaWeb综合案例第一天(注册_验证码_邮箱验证_登录_退出_登陆成功之后的信息展示)_第21张图片
JavaWeb综合案例第一天(注册_验证码_邮箱验证_登录_退出_登陆成功之后的信息展示)_第22张图片

五、登录功能的分析与代码编写

1.新建一个login.html





    
    
    
    编易度假网-登录
    
    
    
    
    
      
    
	
	

	





    
    

2.新建一个LoginServlet

package com.bianyiit.web.servlet;

import com.bianyiit.domain.ResultInfo;
import com.bianyiit.domain.User;
import com.bianyiit.services.UserService;
import com.bianyiit.services.UserServiceImpl;
import com.fasterxml.jackson.databind.ObjectMapper;

import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

@WebServlet("/loginServlet")
public class LoginServlet extends HttpServlet {
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        response.setContentType("application/json;charset=utf-8");
        ResultInfo info = new ResultInfo();
        ObjectMapper objectMapper = new ObjectMapper();

        String username = request.getParameter("username");
        String password = request.getParameter("password");
        String check = request.getParameter("check");

        String checkCode= (String)request.getSession().getAttribute("CHECKCODE_SERVER");
        request.getSession().removeAttribute(checkCode);
        if(checkCode==null||!checkCode.equalsIgnoreCase(check)){
            info.setFlag(false);
            info.setErrorMsg("验证码错误");
            objectMapper.writeValue(response.getWriter(),info);
            return;
        }
        UserService userService=new UserServiceImpl();
        User user = userService.login(username);

        if(user==null){
            info.setFlag(false);
            info.setErrorMsg("登录用户不存在");
        }else {
            if(password==null||!password.equals(user.getPassword())){
                info.setFlag(false);
                info.setErrorMsg("密码不正确");
            }else if(user.getStatus()==null){
                info.setFlag(false);
                info.setErrorMsg("用户未激活");
            }else{
                info.setFlag(true);
                request.getSession().setAttribute("loginUser",user);
            }
        }
        objectMapper.writeValue(response.getWriter(),info);
    }

    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        doPost(request, response);
    }
}

3.业务逻辑处理
JavaWeb综合案例第一天(注册_验证码_邮箱验证_登录_退出_登陆成功之后的信息展示)_第23张图片
4.登录成功之后将用户信息封装到session中
JavaWeb综合案例第一天(注册_验证码_邮箱验证_登录_退出_登陆成功之后的信息展示)_第24张图片
5.登录成功之后,通过ajax返回一个data数据回来,并设置info.flag为true
JavaWeb综合案例第一天(注册_验证码_邮箱验证_登录_退出_登陆成功之后的信息展示)_第25张图片
6.这时我们在header.html中找到一段代码是用于获取用户存在session中的用户名
JavaWeb综合案例第一天(注册_验证码_邮箱验证_登录_退出_登陆成功之后的信息展示)_第26张图片
7.FindLoginUserServlet

package com.bianyiit.web.servlet;

import com.fasterxml.jackson.databind.ObjectMapper;

import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

@WebServlet("/findLoginUserServlet")
public class FindLoginUserServlet extends HttpServlet {
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        Object loginUser = request.getSession().getAttribute("loginUser");
        response.setContentType("application/json;charset=utf-8");
        new ObjectMapper().writeValue(response.getWriter(),loginUser);
    }

    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        doPost(request, response);
    }
}

8.登录的效果演示

六、退出功能的分析与代码编写

1.请求ExitServlet,将存在Session的值清空

2.ExitServlet

package com.bianyiit.web.servlet;

import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

@WebServlet("/exitServlet")
public class ExitServlet extends HttpServlet {
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        request.getSession().invalidate();
        response.sendRedirect("index.html");
    }

    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        doPost(request, response);
    }
}

3.当点击退出之后的效果演示
JavaWeb综合案例第一天(注册_验证码_邮箱验证_登录_退出_登陆成功之后的信息展示)_第27张图片
JavaWeb综合案例第一天(注册_验证码_邮箱验证_登录_退出_登陆成功之后的信息展示)_第28张图片

你可能感兴趣的:(Java修仙之路)