java实现邮箱验证(一个简化的操作与思路,东西不少请一定要看完)

一直不知道邮箱验证是怎么一回事,一直觉得好神奇(因为本人几乎从来不用邮箱)在大佬的带领下还是成功实现了这个功能,话不多说开始操作:

我使用的技术:

java,maven,mysql,一部分相关依赖和jar包.


因为我使用的是QQ邮箱所以需要解锁一部分QQ邮箱的服务:

登录QQ邮箱,在设置->账户面板中开启POP3/SMTP服务:

在这里插入图片描述
注意!
这个服务开启之后会获取一个授权码千万不能丢,非常重要.


先讲一下流程吧

1.在注册页面填写信息,点击注册按钮.

2.后台controller接受到数据判断数据填写是否正确,如果正确保存用户数据并且用户为未激活状态.

3.发送邮件给用户,让用户激活账号.

4.用户激活成功后将用户的状态改为激活状态.


接下来开始代码的操作:

创建一个maven工程

这里我们需要一个JavaMail的坐标(其他坐标大家都不一样我就不放上来了)

<dependencies>
		<!-- 我使用过的是1.5.0的版本 -->
       <dependency>
            <groupId>javax.mail</groupId>
            <artifactId>mail</artifactId>
            <version>1.5.0-b01</version>
            <scope>compile</scope>
        </dependency>
</dependencies>

还需要一个JavaMail的jar包放在共享模块中以供使用,以下是JavaMail代码:

public class MailUtil implements Runnable{
    private String email;// 收件人邮箱
    private String emailKey;// 激活码

    public MailUtil(String email, String emailKey) {
        this.email = email;
        this.emailKey = emailKey;
    }

    @Override
    public void run() {
        // 1.创建连接对象javax.mail.Session
        // 2.创建邮件对象 javax.mail.Message
        // 3.发送一封激活邮件
        String from = "你的QQ号@qq.com";// 发件人电子邮箱
        String host = "smtp.qq.com"; // 指定发送邮件的主机smtp.qq.com(QQ)|smtp.163.com(网易)

        Properties properties;// 获取系统属性
        properties = System.getProperties();

        properties.setProperty("mail.smtp.host", host);// 设置邮件服务器
        properties.setProperty("mail.smtp.auth", "true");// 打开认证

        try {
            //QQ邮箱需要下面这段代码,163邮箱不需要
            MailSSLSocketFactory sf = new MailSSLSocketFactory();
            sf.setTrustAllHosts(true);
            properties.put("mail.smtp.ssl.enable", "true");
            properties.put("mail.smtp.ssl.socketFactory", sf);


            // 1.获取默认session对象
            Session session = Session.getDefaultInstance(properties, new Authenticator() {
                public PasswordAuthentication getPasswordAuthentication() {
                    return new PasswordAuthentication("你的QQ号@qq.com", "刚刚你激活的POP3激活码放这里"); // 发件人邮箱账号、授权码
                }
            });

            // 2.创建邮件对象
            Message message = new MimeMessage(session);
            // 2.1设置发件人
            message.setFrom(new InternetAddress(from));
            // 2.2设置接收人
            message.addRecipient(Message.RecipientType.TO, new InternetAddress(email));
            // 2.3设置邮件主题
            message.setSubject("账号激活");
            // 2.4设置邮件内容
            String content = "<html><head></head><body><h1>这是一封激活邮件,激活请点击以下链接</h1><h3><a href='http://localhost:8080/user/registerAllow?emailKey="
                    + emailKey + "'>http://localhost:8080/user/registerAllow?emailKey=" + emailKey 
                    + "</href></h3></body></html>";
            message.setContent(content, "text/html;charset=UTF-8");
            // 3.发送邮件
            Transport.send(message);
            System.out.println("邮件成功发送!");
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

创建一个数据库表

用户
CREATE TABLE USER (
	uid INT PRIMARY KEY AUTO_INCREMENT,	#用户ID
	username VARCHAR(50),			#用户账号
	PASSWORD VARCHAR(50),			#用户密码
	email VARCHAR(100),			#电子邮件
	emailKey VARCHAR(50),			#生成的随机激活key
	emailKeyTime INT,		#邮箱激活有效验证时间
);

创建一个注册页面

在这里插入图片描述

基本上就这么多,然后我们回到后台:

我的controller层方法的代码(一共两个,第一个负责注册,第二个负责激活):

	//注册
	@PostMapping("/register")
    public BaseResult register(@RequestBody User user){
        if (user.getUsername().equals("") || user.getEmail().equals("")){
            return BaseResult.error("数据填写不完整");
        }
        if(!user.getEmail().matches("^\\w+@(\\w+\\.)+\\w+$")){
            return BaseResult.error("邮箱格式错误");
        }
        try {
            userServiceImpl.register(user);
        } catch (Exception e) {
            e.printStackTrace();
            return BaseResult.error(e.getMessage());
        }
        return BaseResult.ok("注册成功");
    }
    //激活
    @GetMapping("/registerAllow")
    public void emailBeUse(@RequestParam("emailKey") String emailKey){
        //查找数据库查看是否能匹配到拥有该激活码的用户
        try {
            userServiceImpl.registerAllow(emailKey);
        } catch (Exception e) {
            e.printStackTrace();
            System.out.println(e.getMessage());
        }
    }

我的service层方法代码:

	//注册
	public void register(User user) {
        //查找数据库,观察是否有相同的用户数据
        User u = userDao.selectOne(user);
        if (u != null){
            //找到相同用户名,提示已注册.
            throw new RuntimeException("用户名已注册");
        }
        //未注册用户需要生成邮箱激活码进行邮箱验证
        String code = EmailUtils.getCode();
        //保存用户到数据库,显示的是未激活用户
        user.setState(0);
        //存入激活码
        user.setEmailKey(code);
        //存入激活码有效时间(在方法里面我让他往后了十分钟)
        user.setEmailKeyTime(EmailUtils.getKryEndTime());
        try {
            //储存用户
            userDao.insert(user);
        } catch (Exception e) {
            //储存用户失败
            e.printStackTrace();
        }
        //保存用户之后通过线程的方式给用户发送一封邮件
        new Thread(new MailUtil(user.getEmail(),user.getEmailKey())).start();
    }
    //激活
    public void registerAllow(String emailKey) {
        //查询所有用户观察是否有匹配信息
        User user = null;
        user = userDao.selectWithEmailKey(emailKey);
        if (user == null){
            throw new RuntimeException("该用户没有注册,不存在激活码");
        }else{
            //找到了用户,还需要鉴别他的激活时间是否超时
            Long emailKeyTime = user.getEmailKeyTime();
            Long newTime = new Date().getTime();
            if ((newTime - emailKeyTime) > (1000*60*10)){
                //超时
                throw new RuntimeException("用户激活码超时,请重新注册");
            }else{
                //激活成功修改用户状态
                user.setState(1);
                userDao.updateByPrimaryKey(user);
                //跳转登录页面
            }
        }
    }

我方法中的EmailUtils是用来生成激活码的一个工具类,用于生成激活码.

操作到这里基本已经结束了,具体细节还请大家自己动手解决.下面是图示解析:
在这里插入图片描述
数据库:
在这里插入图片描述


在这里插入图片描述
数据库:

在这里插入图片描述

激活完成

在这里插入图片描述

发布了38 篇原创文章 · 获赞 19 · 访问量 3698

猜你喜欢

转载自blog.csdn.net/Ryan_black/article/details/104208283