Java实现注册登录与邮箱发送账号验证激活功能

 更新时间:2022年12月21日 09:04:02   作者:秋名山码民  
这篇文章主要介绍了Java实现注册登录与邮箱发送账号验证激活功能,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习吧

前言

项目流程图如下:

这里我们通过:

  • 163邮箱来实现激活码发送
  • qq邮箱来进行接收

学习之前需要掌握的知识

  • springboot的基本使用方法
  • mysql的使用
  • mybatis的简单使用

项目环境搭建

这里我们直接使用 Spring Initializr 初始化 Spring Boot 项目

环境依赖选择:

  • lombok简化开发,使用注解,避免写重复性代码
  • SpringWeb,实现一个前后端的数据交互(一个登录注册验证,没必要写前后端分离)
  • MySQL
  • MyBatis

完整的pom文件

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.7.6</version>
        <relativePath/> <!-- lookup parent from repository -->
    </parent>
    <groupId>com.demo</groupId>
    <artifactId>email-login-register</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <name>email-login-register</name>
    <description>Demo project for Spring Boot</description>
    <properties>
        <java.version>1.8</java.version>
    </properties>
    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-mail</artifactId>
        </dependency>
        <dependency>
            <groupId>org.thymeleaf</groupId>
            <artifactId>thymeleaf-spring5</artifactId>
        </dependency>
        <dependency>
            <groupId>org.thymeleaf.extras</groupId>
            <artifactId>thymeleaf-extras-java8time</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-thymeleaf</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <dependency>
            <groupId>org.mybatis.spring.boot</groupId>
            <artifactId>mybatis-spring-boot-starter</artifactId>
            <version>3.0.0</version>
        </dependency>
        <dependency>
            <groupId>com.mysql</groupId>
            <artifactId>mysql-connector-j</artifactId>
            <scope>runtime</scope>
        </dependency>
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <optional>true</optional>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>cn.hutool</groupId>
            <artifactId>hutool-all</artifactId>
            <version>5.8.0</version>
        </dependency>
        <dependency>
            <groupId>commons-lang</groupId>
            <artifactId>commons-lang</artifactId>
            <version>2.6</version>
        </dependency>
    </dependencies>
    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
                <configuration>
                    <excludes>
                        <exclude>
                            <groupId>org.projectlombok</groupId>
                            <artifactId>lombok</artifactId>
                        </exclude>
                    </excludes>
                </configuration>
            </plugin>
        </plugins>
    </build>
</project>

application.yml配置

server:
  port: 8001

spring:
  datasource:
    driver-class-name: com.mysql.cj.jdbc.Driver
    url: jdbc:mysql://localhost:3306/email?serverTimezone=Asia/Shanghai&useUnicode=true&characterEncoding=utf8&useSSL=false
    username: root
    password: qwer123.
  mail:
    protocol: smtp # 邮件协议
    host: smtp.163.com # 网易邮箱 smtp 服务器地址
    port: 25
    username: mashengmingming@163.com # 发件人邮箱地址
    password:     # 授权码
    default-encoding: utf-8 # 编码字符集
    properties:
      mail:
        debug: true # 开启 debug 模式以后会完整打印邮件发送过程的日志

mybatis:
  configuration:
    map-underscore-to-camel-case: true # 开启驼峰映射

数据库的搭建

注册,登录页面需要的字段:

基本字段:id,email,password 常用的拓展字段:

activation_time                    // 激活失效时间
confirm_code                // 确认代码    
is_vaild                    // 是否可用 0-不可用 1-可用    
salt                        // 加密盐
gmt_create                    // 创建时间
gmt_modified                // 修改时间

具体的建表语句

SET NAMES utf8mb4;
SET FOREIGN_KEY_CHECKS = 0;
DROP TABLE IF EXISTS `user`;
CREATE TABLE `user`  (
  `id` bigint NOT NULL AUTO_INCREMENT COMMENT '主键\r\n',
  `email` varchar(255) CHARACTER SET utf8mb3 COLLATE utf8mb3_general_ci NULL DEFAULT NULL COMMENT '邮箱',
  `password` varchar(255) CHARACTER SET utf8mb3 COLLATE utf8mb3_general_ci NULL DEFAULT NULL COMMENT '密码',
  `activation_time` timestamp NULL DEFAULT NULL COMMENT '激活失效时间',
  `confirm_code` varchar(255) CHARACTER SET utf8mb3 COLLATE utf8mb3_general_ci NULL DEFAULT NULL COMMENT '确认码',
  `is_vaild` int NULL DEFAULT NULL COMMENT '是否可用,0不可用,1可用',
  `salt` varchar(255) CHARACTER SET utf8mb3 COLLATE utf8mb3_general_ci NULL DEFAULT NULL COMMENT '加密盐',
  `gmt_create` timestamp NULL DEFAULT NULL COMMENT '创建时间',
  `gmt_modified` timestamp NULL DEFAULT NULL COMMENT '更新时间',
  PRIMARY KEY (`id`) USING BTREE,
  UNIQUE INDEX `email`(`email` ASC) USING BTREE
) ENGINE = InnoDB AUTO_INCREMENT = 9 CHARACTER SET = utf8mb3 COLLATE = utf8mb3_general_ci ROW_FORMAT = Dynamic;
INSERT INTO `user` VALUES (8, '986438626@qq.com', '09eff3f9a0817674c4d79c01eb156092', '2022-12-20 17:08:09', '1604765517418205184', 1, 'bn1sqy', '2022-12-19 17:08:09', '2022-12-19 17:08:09');
SET FOREIGN_KEY_CHECKS = 1;

前端页面的搭建

前后端不分离下,我们前端页面一般放到templates下面

登录

<!DOCTYPE html>
<html>
<head>
    <!-- Standard Meta -->
    <meta charset="utf-8" />
    <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0">
    <!-- Site Properties -->
    <title>Login Example - Semantic</title>
    <link rel="stylesheet" type="text/css" href="https://cdn.jsdelivr.net/npm/semantic-ui@2.4.2/dist/components/reset.css">
    <link rel="stylesheet" type="text/css" href="https://cdn.jsdelivr.net/npm/semantic-ui@2.4.2/dist/components/site.css">
    <link rel="stylesheet" type="text/css" href="https://cdn.jsdelivr.net/npm/semantic-ui@2.4.2/dist/components/container.css">
    <link rel="stylesheet" type="text/css" href="https://cdn.jsdelivr.net/npm/semantic-ui@2.4.2/dist/components/grid.css">
    <link rel="stylesheet" type="text/css" href="https://cdn.jsdelivr.net/npm/semantic-ui@2.4.2/dist/components/header.css">
    <link rel="stylesheet" type="text/css" href="https://cdn.jsdelivr.net/npm/semantic-ui@2.4.2/dist/components/image.css">
    <link rel="stylesheet" type="text/css" href="https://cdn.jsdelivr.net/npm/semantic-ui@2.4.2/dist/components/menu.css">
    <link rel="stylesheet" type="text/css" href="https://cdn.jsdelivr.net/npm/semantic-ui@2.4.2/dist/components/divider.css">
    <link rel="stylesheet" type="text/css" href="https://cdn.jsdelivr.net/npm/semantic-ui@2.4.2/dist/components/segment.css">
    <link rel="stylesheet" type="text/css" href="https://cdn.jsdelivr.net/npm/semantic-ui@2.4.2/dist/components/form.css">
    <link rel="stylesheet" type="text/css" href="https://cdn.jsdelivr.net/npm/semantic-ui@2.4.2/dist/components/input.css">
    <link rel="stylesheet" type="text/css" href="https://cdn.jsdelivr.net/npm/semantic-ui@2.4.2/dist/components/button.css">
    <link rel="stylesheet" type="text/css" href="https://cdn.jsdelivr.net/npm/semantic-ui@2.4.2/dist/components/list.css">
    <link rel="stylesheet" type="text/css" href="https://cdn.jsdelivr.net/npm/semantic-ui@2.4.2/dist/components/message.css">
    <link rel="stylesheet" type="text/css" href="https://cdn.jsdelivr.net/npm/semantic-ui@2.4.2/dist/components/icon.css">
    <script src="https://cdn.jsdelivr.net/npm/jquery@3.6.0/dist/jquery.min.js"></script>
    <script src="https://cdn.jsdelivr.net/npm/semantic-ui@2.4.2/dist/components/form.js"></script>
    <script src="https://cdn.jsdelivr.net/npm/semantic-ui@2.4.2/dist/components/transition.js"></script>
    <style type="text/css">
        body {
            background-color: #DADADA;
        }
        body > .grid {
            height: 100%;
        }
        .image {
            margin-top: -100px;
        }
        .column {
            max-width: 450px;
        }
    </style>
    <script>
        $(document)
            .ready(function() {
                $('.ui.form')
                    .form({
                        fields: {
                            email: {
                                identifier  : 'email',
                                rules: [
                                    {
                                        type   : 'empty',
                                        prompt : 'Please enter your e-mail'
                                    },
                                    {
                                        type   : 'email',
                                        prompt : 'Please enter a valid e-mail'
                                    }
                                ]
                            },
                            password: {
                                identifier  : 'password',
                                rules: [
                                    {
                                        type   : 'empty',
                                        prompt : 'Please enter your password'
                                    },
                                    {
                                        type   : 'length[6]',
                                        prompt : 'Your password must be at least 6 characters'
                                    }
                                ]
                            }
                        }
                    })
                ;
            })
        ;
    </script>
</head>
<body>
<div class="ui middle aligned center aligned grid">
    <div class="column">
        <h2 class="ui teal image header">
           <img alt="" src="./img/logo.png" class="image">
            <div class="content">
                LoginDemo
            </div>
        </h2>
        <form class="ui large form" onsubmit="return false">
            <div class="ui stacked segment">
                <div class="field">
                    <div class="ui left icon input">
                        <i class="user icon"></i>
                        <input type="text" id="email" name="email" placeholder="E-mail address">
                    </div>
                </div>
                <div class="field">
                    <div class="ui left icon input">
                        <i class="lock icon"></i>
                        <input type="password" id="password" name="password" placeholder="Password">
                    </div>
                </div>
                <div class="ui fluid large teal submit button" id="login">登录</div>
            </div>
            <div class="ui error message"></div>
        </form>
        <div class="ui message">
            <a href="/registry">注册</a>
        </div>
    </div>
</div>
<script type="application/javascript" charset="UTF-8">
    $("#login").on("click",function () {
        $.ajax({
            url:"users/login",
            type:"POST",
            data:{
                email:$("#email").val(),
                password:$("#password").val(),
            },
            resultType:"JSON",
            success:function (result) {
                alert(result.msg);
            },
            error:function (result) {
                alert(result.msg);
            }
        })
    })
</script>
</body>
</html>

注册

<!DOCTYPE html>
<html>
<head>
    <!-- Standard Meta -->
    <meta charset="utf-8" />
    <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0">
    <!-- Site Properties -->
    <title>LoginDemo</title>
    <link rel="stylesheet" type="text/css" href="https://cdn.jsdelivr.net/npm/semantic-ui@2.4.2/dist/components/reset.css">
    <link rel="stylesheet" type="text/css" href="https://cdn.jsdelivr.net/npm/semantic-ui@2.4.2/dist/components/site.css">
    <link rel="stylesheet" type="text/css" href="https://cdn.jsdelivr.net/npm/semantic-ui@2.4.2/dist/components/container.css">
    <link rel="stylesheet" type="text/css" href="https://cdn.jsdelivr.net/npm/semantic-ui@2.4.2/dist/components/grid.css">
    <link rel="stylesheet" type="text/css" href="https://cdn.jsdelivr.net/npm/semantic-ui@2.4.2/dist/components/header.css">
    <link rel="stylesheet" type="text/css" href="https://cdn.jsdelivr.net/npm/semantic-ui@2.4.2/dist/components/image.css">
    <link rel="stylesheet" type="text/css" href="https://cdn.jsdelivr.net/npm/semantic-ui@2.4.2/dist/components/menu.css">
    <link rel="stylesheet" type="text/css" href="https://cdn.jsdelivr.net/npm/semantic-ui@2.4.2/dist/components/divider.css">
    <link rel="stylesheet" type="text/css" href="https://cdn.jsdelivr.net/npm/semantic-ui@2.4.2/dist/components/segment.css">
    <link rel="stylesheet" type="text/css" href="https://cdn.jsdelivr.net/npm/semantic-ui@2.4.2/dist/components/form.css">
    <link rel="stylesheet" type="text/css" href="https://cdn.jsdelivr.net/npm/semantic-ui@2.4.2/dist/components/input.css">
    <link rel="stylesheet" type="text/css" href="https://cdn.jsdelivr.net/npm/semantic-ui@2.4.2/dist/components/button.css">
    <link rel="stylesheet" type="text/css" href="https://cdn.jsdelivr.net/npm/semantic-ui@2.4.2/dist/components/list.css">
    <link rel="stylesheet" type="text/css" href="https://cdn.jsdelivr.net/npm/semantic-ui@2.4.2/dist/components/message.css">
    <link rel="stylesheet" type="text/css" href="https://cdn.jsdelivr.net/npm/semantic-ui@2.4.2/dist/components/icon.css">
    <script src="https://cdn.jsdelivr.net/npm/jquery@3.6.0/dist/jquery.min.js"></script>
    <script src="https://cdn.jsdelivr.net/npm/semantic-ui@2.4.2/dist/components/form.js"></script>
    <script src="https://cdn.jsdelivr.net/npm/semantic-ui@2.4.2/dist/components/transition.js"></script>
    <style type="text/css">
        body {
            background-color: #DADADA;
        }
        body > .grid {
            height: 100%;
        }
        .image {
            margin-top: -100px;
        }
        .column {
            max-width: 450px;
        }
    </style>
    <script>
        $(document)
            .ready(function() {
                $('.ui.form')
                    .form({
                        fields: {
                            email: {
                                identifier  : 'email',
                                rules: [
                                    {
                                        type   : 'empty',
                                        prompt : 'Please enter your e-mail'
                                    },
                                    {
                                        type   : 'email',
                                        prompt : 'Please enter a valid e-mail'
                                    }
                                ]
                            },
                            password: {
                                identifier  : 'password',
                                rules: [
                                    {
                                        type   : 'empty',
                                        prompt : 'Please enter your password'
                                    },
                                    {
                                        type   : 'length[6]',
                                        prompt : 'Your password must be at least 6 characters'
                                    }
                                ]
                            }
                        }
                    })
                ;
            })
        ;
    </script>
</head>
<body>
<div class="ui middle aligned center aligned grid">
    <div class="column">
        <h2 class="ui teal image header">
         <!--   <img alt="" src="./img/logo.png" class="image">-->
            <div class="content">
                LoginDemo
            </div>
        </h2>
        <form class="ui large form" onsubmit="return false">
            <div class="ui stacked segment">
                <div class="field">
                    <div class="ui left icon input">
                        <i class="user icon"></i>
                        <input type="text" id="email" name="email" placeholder="E-mail address">
                    </div>
                </div>
                <div class="field">
                    <div class="ui left icon input">
                        <i class="lock icon"></i>
                        <input type="password" id="password" name="password" placeholder="Password">
                    </div>
                </div>
                <div class="field">
                    <div class="ui left icon input">
                        <i class="lock icon"></i>
                        <input type="password" name="repassword" placeholder="rePassword">
                    </div>
                </div>
                <div class="ui fluid large teal submit button" id="registry">注册</div>
            </div>
            <div class="ui error message"></div>
        </form>
        <div class="ui message">
             <a href="/login">登录</a>
        </div>
    </div>
</div>
<!--交互方法-->
<script type="application/javascript" charset="UTF-8">
        $("#registry").on("click",function () {
            $.ajax({
                url:"/users/register", /*请求链接*/
                type:"POST",    /*请求方法*/
                data:{ /*获取表当数据*/
                    email:$("#email").val(),
                    password:$("#password").val(),
                },
                resultType:"JSON", /*数据格式*/
                success:function (result){
                    alert(result.msg);
                },
                error:function (result) {
                    alert(result.msg);
                }
            })
        })
</script>
</body>
</html>

发送邮件格式

<html>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<body>
<div>
    Email 地址验证<br>
    欢迎注册LoginDemo,这是一封账号激活邮件,只有激活账号后才能登录网站,点击下方链接即可激活账号!<br>
    激活链接有效期为24小时,请在规定时间内激活账号!<br>
    -----------------------------------------------------------------------------<br>
    -----------------------------------------------------------------------------<br>
    <a th:href="@{${activationUrl}}"><span th:text="${activationUrl}"></span></a><br>
    -----------------------------------------------------------------------------<br>
    -----------------------------------------------------------------------------<br>
    感谢您的访问,祝您生活愉快!<br>
</div>
</body>
</html>

长这个样子:

后端代码

格式

典型的分层模型,

pojo

package com.expamle.emailloginregister.pojo;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import java.io.Serializable;
import java.time.LocalDateTime;
@Data
@NoArgsConstructor
@AllArgsConstructor
public class User implements Serializable {
        private Integer id; // 主键Id
        private String email; // 邮箱
        private String password; // 密码 md5+盐
       /* @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm")*/
        private LocalDateTime activationTime; // 激活失效时间
        private String confirmCode; // 确认代码
        private Integer isVaild; // 是否可用 0-不可用 1-可用
        private String salt; // 加密盐
/*
        @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm")
*/
        private LocalDateTime gmtCreate; // 创建时间
/*
        @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm")
*/
        private LocalDateTime gmtModified; // 修改时间
}

mapper

主要通过mybatis来写一些与user相关的sql语句

package com.expamle.emailloginregister.mapper;
import com.expamle.emailloginregister.pojo.User;
import org.apache.ibatis.annotations.*;
import java.util.List;
@Mapper
public interface UserMapper {
    /**
     * 注册插入用户信息
     * */
    @Insert("insert into user(email,password,activation_time,confirm_code,is_vaild,salt,gmt_create,gmt_modified)" +
            "values(#{email},#{password},#{activationTime},#{confirmCode},#{isVaild},#{salt},#{gmtCreate},#{gmtModified})")
    int insertUser(User user);
    /**
     * 根据confirm_code查询与用户是否已激活
     * confirm_code
     * is_vaild
     * */
    @Select("select email,activation_time from user where confirm_code = #{confirmCode} and is_vaild = 0")
    User findUserByConfirmCode(@Param("confirmCode") String confirmCode);
    /**
     * 根据激活码查询用户 并 修改状态值
     * */
    @Update("update user set is_vaild=1 where confirm_code = #{confirmCode}")
    int confirmUser(@Param("confirmCode") String confirmCode);
    /**
     * 根据邮箱查询账号
     * */
    @Select("select email,password,salt from user where email=#{email} and is_vaild=1")
    List<User> findUserByEmail(@Param("email") String email);
    /**
     * 用户查重
     * */
    @Select("select count(*) from user where email=#{email} limit 1")
    int emailExist(@Param("email") String email);
}

Controller

与前端页面进行交互,负责一个登录,注册数据的提交和响应

SystemController

package com.expamle.emailloginregister.controller;
import com.expamle.emailloginregister.pojo.User;
import com.expamle.emailloginregister.service.UserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
/**
*@Controller 不可使用RestControoler
*使用RestController要进行一个封装
*/
@Controller
public class SystemController {
    @Autowired
    private UserService userService;

    /**
     * 登录
     * */
    @GetMapping("/login")
    public String login(){

       return "login";
    }
    /**
     * 注册
     * */
    @GetMapping("/registry")
    public String registry(User user){
        return "registry";
    }
}

UserController

package com.expamle.emailloginregister.controller;
import com.expamle.emailloginregister.pojo.User;
import com.expamle.emailloginregister.service.UserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import java.util.Map;
@RestController
@RequestMapping("users")
public class UserController {
@Autowired
    private UserService userService;
    /**
     * 注册账号
     * */
    @PostMapping("register")
    public Map<String,Object> registery(User user){
      Map<String,Object> map  =  userService.createAccount(user);
        return map;
    }
    /**
     * 用户登录
     * */
    @PostMapping("login")
    public Map<String,Object> login(User user){
        Map<String,Object> map = userService.accountLogin(user);
        return map;
    }
    /**
     * 账号激活
     * 激活码附在请求后
     *
     * */
    @GetMapping("activation")
    public Map<String,Object> activationAccount(String confirmCode){
        Map<String,Object> map = userService.activationAccount(confirmCode);
        return map;
    }
}

service

先写俩个接口,在Impl中进行实现,

EmailServiceImpl

package com.expamle.emailloginregister.service;
public interface EmailService {
    void sendEmail(String email,String activationUrl);
}

实现sendEmail

package com.expamle.emailloginregister.service.Impl;
import com.expamle.emailloginregister.service.EmailService;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.mail.javamail.JavaMailSender;
import org.springframework.mail.javamail.MimeMessageHelper;
import org.springframework.stereotype.Service;
import org.thymeleaf.TemplateEngine;
import org.thymeleaf.context.Context;
import javax.annotation.Resource;
import javax.mail.MessagingException;
import javax.mail.internet.MimeMessage;
import java.util.Date;
/**
 * 发送邮件相关业务
 * */
@Service
public class EmailServiceImpl implements EmailService {
    // 引入配置文件属性
    @Value("${spring.mail.username}")
    private String sendUsername;
    // javamain mail依赖方法---此方法无法使用autowird注入,javaMailSender不是springboot的方法
    @Resource
    private JavaMailSender javaMailSender;
    @Resource //同上
    private TemplateEngine templateEngine;
    public void sendEmail(String email,String activationUrl){
        // 创建邮件对象
        MimeMessage mimeMessage = javaMailSender.createMimeMessage();
        try {
            /**
             * MineMessagehelper---设置邮件相关内容
             * @Params1 邮件对象
             * @Params2 是否发送多封邮件
             * */
            MimeMessageHelper message = new MimeMessageHelper(mimeMessage,true);
            // 设置邮件主题
            message.setSubject("注册账号激活");
            // 设置邮件发送者
            message.setFrom(sendUsername);
            // 设置邮件接收者,可多个
            message.setTo(email);
            // 设置邮件抄送人
           /* message.setCc();*/
            // 设置邮件隐秘抄送人,可多个
            /*message.setBcc();*/
            // 设置邮件发送日期
            message.setSentDate(new Date());
            // 创建上下文环境--thym依赖提供方法,使用当前本地前端
            Context context = new Context();
            // 邮件中传递的链接
            context.setVariable("activationUrl",activationUrl);
            // 映射html文件
            String text = templateEngine.process("activation-account.html",context);
            // 设置邮件正文-true-是否是html模板
            message.setText(text,true);

                   } catch (MessagingException e) {
            e.printStackTrace();
        }
        // 发送邮件
        javaMailSender.send(mimeMessage);
    }
}

UserService

package com.expamle.emailloginregister.service;
import com.expamle.emailloginregister.pojo.User;
import org.springframework.transaction.annotation.Transactional;
import java.util.Map;
@Transactional
public interface UserService {
    Map<String,Object> createAccount(User user);
    Map<String, Object> accountLogin(User user);
    Map<String, Object> activationAccount(String confirmCode);
}

具体实现

package com.expamle.emailloginregister.service.Impl;
import cn.hutool.core.util.IdUtil;
import cn.hutool.core.util.RandomUtil;
import cn.hutool.crypto.SecureUtil;
import com.expamle.emailloginregister.mapper.UserMapper;
import com.expamle.emailloginregister.pojo.User;
import com.expamle.emailloginregister.service.EmailService;
import com.expamle.emailloginregister.service.UserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.time.LocalDateTime;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
@Service
public class UserServiceImpl implements UserService {
   @Autowired
   private UserMapper userMapper;
   @Autowired
   private EmailService emailService;
   /**
    * 用户注册
    * */
    @Override
    public Map<String,Object> createAccount(User user) {
        // 统一返回对象
        Map<String,Object> result = new HashMap<>();
        /**
         * 注册--构建User对象内的数据
         *  前端返回参数 email、password
         * */
        // 判断邮箱是否已经存在
        int emailExist = userMapper.emailExist(user.getEmail());
        if (emailExist == 1){
            result.put("code",400);
            result.put("msg","用户已存在");
            return result;
        }
        //开始构建user数据
        // 激活码--hutool工具生成雪花算法
        String confirmCode = IdUtil.getSnowflake(1,1).nextIdStr();
        user.setConfirmCode(confirmCode);
        // 加密密码  password+盐+md5
        String password = user.getPassword();
        String salt = RandomUtil.randomString(6); // hutool随机生成6个字符
        String md5Pwd = SecureUtil.md5(password+salt);
        // 设置user参数、salt、password
        user.setSalt(salt);
        user.setPassword(md5Pwd);
        // 是否已激活 默认-0 未激活
        user.setIsVaild(0);
        // 激活码有效期
        LocalDateTime activationTime = LocalDateTime.now().plusDays(1); // 当前时间增加1天时间
        user.setActivationTime(activationTime);
        // 创建时间
        LocalDateTime nowTime = LocalDateTime.now();
        user.setGmtCreate(nowTime);
        user.setGmtModified(nowTime);
        // 用户信息插入数据库
        int insertUser = userMapper.insertUser(user);
        // 判断数据库写入是否成功并返回相关信息
        if (insertUser > 0){
            // 准备激活链接
            String activationUrl ="http://localhost:8001/users/activation?confirmCode="+confirmCode;
            //发送邮箱信息
             emailService.sendEmail(user.getEmail(), activationUrl);
            result.put("code",200);
            result.put("msg","注册成功,请前往邮箱激活账号");
            return result;
        }else{
            result.put("code",400);
            result.put("msg","注册失败");
            return result;
        }
    }
    public static void main(String[] args) {
        String a = SecureUtil.md5("123456"+"qldp40");
        System.out.println(a);
    }
    /**
     * 用户登录
     * */
    @Override
    public Map<String, Object> accountLogin(User user) {
        // 统一返回数据
        Map<String,Object> result = new HashMap<>();
        // 前端数据校验
       if (user.getEmail() == null || user.getEmail().isEmpty() ||
            user.getPassword() == null || user.getPassword().isEmpty()
           ){
                result.put("code",400);
                result.put("msg","请输入账号和密码");
                return result;
       }
       // 查询用户是否在数据库中
        List<User> users = userMapper.findUserByEmail(user.getEmail());
        // 判断用户是否异常
        if (users == null || users.isEmpty()){
            result.put("code",400);
            result.put("msg","账号未注册或未激活");
            return result;
        }
        // 查询出多个账号
        if (users.size()>1){
            result.put("code",400);
            result.put("msg","账号异常请联系管理员");
            return result;
        }
        // 得到唯一用户-判断账号是否激活
        User DbUser = users.get(0);
        // 校验密码-获取加密数据
        String salt = DbUser.getSalt();
        String md5Pwd = SecureUtil.md5(user.getPassword()+salt);
        /**
         * DbUser.getPassword().equals(md5Pwd)---可以匹配
         * md5Pwd.equals(DbUser.getPassword())---无法匹配 ??????
         * */
        if (DbUser.getPassword().equals(md5Pwd)){
            result.put("code",200);
            result.put("msg","登录成功");
            return result;
        }else {
            result.put("code",400);
            result.put("msg","账号或密码有误");
            return result;
        }
    }
    /**
     * 激活账号
     * */
    @Override
    public Map<String, Object> activationAccount(String confirmCode) {
        // 统一返回参数
        Map<String, Object> map = new HashMap<>();
        // 通过confirmCount查询用户
        User user = userMapper.findUserByConfirmCode(confirmCode);
        System.out.println(user.toString());
        if (user == null ){
            map.put("code",400);
            map.put("msg","账号未注册");
            return map;
        }
        // 判断激活码有效期
        // 当前时间是否在激活码截止期之后
        boolean after = LocalDateTime.now().isAfter(user.getActivationTime());
        if (after){
            map.put("code",400);
            map.put("msg","链接已失效,请重新获取激活码");
            return map;
        }
        // 激活账号,修改状态为 1
        int confirmUser = userMapper.confirmUser(confirmCode);
        if (confirmUser == 1){
            map.put("code",200);
            map.put("msg","激活账号成功");
            return map;
        }else{
            map.put("code",400);
            map.put("msg","激活账号失败");
            return map;
        }
    }
}

最后

码云完整代码及部署教程:

https://gitee.com/Vamye/LoginDemo

参考b站视频教程

到此这篇关于Java实现注册登录与邮箱发送账号验证激活功能的文章就介绍到这了,更多相关Java注册登录内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • Java Flink与kafka实现实时告警功能过程

    Java Flink与kafka实现实时告警功能过程

    这篇文章主要介绍了Java Flink与kafka实现实时告警功能,本文通过示例代码给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2023-01-01
  • java获取新insert数据自增id的实现方法

    java获取新insert数据自增id的实现方法

    这篇文章主要介绍了java获取新insert数据自增id的实现方法,在具体生成id的时候,我们的操作顺序一般是:先在主表中插入记录,然后获得自动生成的id,以它为基础插入从表的记录,需要的朋友可以参考下
    2019-06-06
  • Java使用DateTimeFormatter格式化输入的日期时间

    Java使用DateTimeFormatter格式化输入的日期时间

    这篇文章主要介绍了Java使用DateTimeFormatter格式化输入的日期时间,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2020-01-01
  • Java字符串中删除指定子字符串的方法简介

    Java字符串中删除指定子字符串的方法简介

    这篇文章主要介绍了Java字符串中删除指定子字符串的方法,是Java入门学习中的基础知识,需要的朋友可以参考下
    2015-11-11
  • 深入学习java位运算的基础知识

    深入学习java位运算的基础知识

    位运算是直接对整数在内存中的二进制位进行操作吗,位运算即可以节约内存,同时使程序速度更快效率更高。文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,下面我们来一起学习下吧
    2019-06-06
  • Java8中的类型注解浅析

    Java8中的类型注解浅析

    这篇文章主要介绍了Java8中的类型注解浅析,java8之前,注解只能是在声明的地方所使用,java8里面的注解则可以应用在任何地方,需要的朋友可以参考下
    2014-06-06
  • java8新特性 stream流的方式遍历集合和数组操作

    java8新特性 stream流的方式遍历集合和数组操作

    这篇文章主要介绍了java8新特性 stream流的方式遍历集合和数组操作,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2020-08-08
  • java常用工具类 Date日期、Mail邮件工具类

    java常用工具类 Date日期、Mail邮件工具类

    这篇文章主要为大家详细介绍了java常用工具类,包括Date日期、Mail邮件工具类,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2019-05-05
  • 解决zuulGateway网关添加路由异常熔断问题

    解决zuulGateway网关添加路由异常熔断问题

    这篇文章主要介绍了解决zuulGateway网关添加路由异常熔断问题,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2020-10-10
  • 深度优先与广度优先Java实现代码示例

    深度优先与广度优先Java实现代码示例

    这篇文章主要介绍了深度优先与广度优先Java实现代码示例,具有一定借鉴价值,需要的朋友可以参考下。
    2017-12-12

最新评论