SpringBoot中实现注册用户发送激活邮件功能

ゝ一世哀愁。 2022-12-10 07:10 441阅读 0赞

在上一章节中,我带大家学习了SpringBoot中如何发送各种类型的邮件,接下来我再带大家实现一下,在实际开发中的邮件发送功能。

需求分析: 很多网站注册时,都会给我们的注册邮箱发送一封激活邮件,里面是一串连接,点击链接激活之后才可以登录,今天咱们就实现这个功能。

一. 发送激活邮件实现步骤

1. 创建web项目

我们按照之前的经验,创建一个web程序,并将之改造成Spring Boot项目,具体过程略。

a2b25bb95bd4912fdd502ba46c31b86e.png

2. 添加依赖包

  1. <dependency>
  2. <groupId>org.springframework.boot</groupId>
  3. <artifactId>spring-boot-starter-data-jpa</artifactId>
  4. </dependency>
  5. <!--MySQL-->
  6. <dependency>
  7. <groupId>mysql</groupId>
  8. <artifactId>mysql-connector-java</artifactId>
  9. <scope>runtime</scope>
  10. </dependency>
  11. <!--Druid数据库连接池-->
  12. <dependency>
  13. <groupId>com.alibaba</groupId>
  14. <artifactId>druid-spring-boot-starter</artifactId>
  15. <version>1.1.10</version>
  16. </dependency>
  17. <!--邮件-->
  18. <dependency>
  19. <groupId>org.springframework.boot</groupId>
  20. <artifactId>spring-boot-starter-mail</artifactId>
  21. </dependency>
  22. <dependency>
  23. <groupId>org.springframework.boot</groupId>
  24. <artifactId>spring-boot-starter-freemarker</artifactId>
  25. </dependency>
  26. <!--thymeleaf-->
  27. <dependency>
  28. <groupId>org.springframework.boot</groupId>
  29. <artifactId>spring-boot-starter-thymeleaf</artifactId>
  30. </dependency>

3. 创建application.yml配置文件

把配置文件中关于数据库等的配置,全部改写成自己的配置信息。

  1. spring:
  2. http:
  3. encoding:
  4. charset: UTF-8
  5. force: true
  6. enabled: true
  7. datasource:
  8. url: jdbc:mysql://localhost:3306/db6?characterEncoding=utf-8&useSSL=false&serverTimezone=UTC
  9. username: root
  10. password: syc
  11. driverClassName: com.mysql.jdbc.Driver
  12. type: com.alibaba.druid.pool.DruidDataSource
  13. jpa:
  14. database: mysql
  15. show-sql: true
  16. hibernate:
  17. ddl-auto: update
  18. naming:
  19. physical-strategy: org.hibernate.boot.model.naming.PhysicalNamingStrategyStandardImpl
  20. database-platform: org.hibernate.dialect.MySQL5Dialect
  21. #页面模板配置
  22. thymeleaf:
  23. prefix: classpath:/templates/
  24. suffix: .html
  25. mail:
  26. host: smtp.qq.com
  27. from: 2312119590@qq.com
  28. username: 2312119590@qq.com
  29. password: xxx(自己的授权码)
  30. protocol: smtp
  31. default-encoding: UTF-8
  32. server:
  33. tomcat:
  34. uri-encoding: UTF-8

4. 封装User实体类

  1. package com.yyg.boot.entity;
  2. import lombok.Data;
  3. import javax.persistence.*;
  4. import java.io.Serializable;
  5. /**
  6. * @Author 一一哥Sun
  7. * @Date Created in 2020/4/20
  8. * @Description Description
  9. */
  10. @Data
  11. @Entity
  12. @Table(name = "user")
  13. public class User implements Serializable {
  14. @Id
  15. @GeneratedValue(strategy = GenerationType.IDENTITY)
  16. private Integer id;
  17. private String username;
  18. private String password;
  19. @Column(name = "usermail")
  20. private String userMail;
  21. /**
  22. * 状态:0代表未激活,1代表激活
  23. */
  24. private Integer status;
  25. /**
  26. * 用UUID生成一段数字,发送到用户邮箱,当用户点击链接时,再做一个校验,
  27. * 如果用户传来的code跟我们发送的code一致,则更改状态为“1”来激活用户.
  28. */
  29. private String code;
  30. }

5. 配置数据源

  1. package com.yyg.boot.config;
  2. import com.alibaba.druid.pool.DruidDataSource;
  3. import org.springframework.boot.context.properties.ConfigurationProperties;
  4. import org.springframework.context.annotation.Bean;
  5. import org.springframework.context.annotation.Configuration;
  6. /**
  7. * @Author 一一哥Sun
  8. * @Date Created in 2020/4/20
  9. * @Description Description
  10. */
  11. @Configuration
  12. public class DataSourceConfig {
  13. @Bean
  14. @ConfigurationProperties(prefix = "spring.datasource")
  15. public DruidDataSource druidConfig(){
  16. return new DruidDataSource();
  17. }
  18. }

6. 创建JPA的仓库类

  1. package com.yyg.boot.repository;
  2. import com.yyg.boot.entity.User;
  3. import org.springframework.data.jpa.repository.JpaRepository;
  4. import org.springframework.data.jpa.repository.JpaSpecificationExecutor;
  5. import org.springframework.stereotype.Repository;
  6. /**
  7. * @Author 一一哥Sun
  8. * @Date Created in 2020/4/20
  9. * @Description Description
  10. */
  11. @Repository
  12. public interface UserRepository extends JpaRepository<User,Integer>,JpaSpecificationExecutor<User> {
  13. User findUserByCode(String code);
  14. User findByUsernameAndPassword(String username,String password);
  15. }

7. 创建生成UUID的工具类

  1. package com.yyg.boot.utils;
  2. import java.util.UUID;
  3. /**
  4. * @Author 一一哥Sun
  5. * @Date Created in 2020/4/20
  6. * @Description Description
  7. */
  8. public class UUIDUtil {
  9. public static String getUUID(){
  10. return UUID.randomUUID().toString().replace("-","");
  11. }
  12. }

8. 定义发送邮件的工具类

定义发送邮件工具类接口

  1. package com.yyg.boot.mail;
  2. /**
  3. * @Author 一一哥Sun
  4. * @Date Created in 2020/4/20
  5. * @Description 封装一个发邮件的接口,方便后边直接调用.
  6. */
  7. public interface IMailService {
  8. /**
  9. * 发送文本邮件
  10. *
  11. * @param to 收件人
  12. * @param subject 主题
  13. * @param content 内容
  14. */
  15. void sendSimpleMail(String to, String subject, String content);
  16. /**
  17. * 发送HTML邮件
  18. *
  19. * @param to 收件人
  20. * @param subject 主题
  21. * @param content 内容
  22. */
  23. void sendHtmlMail(String to, String subject, String content);
  24. /**
  25. * 发送带附件的邮件
  26. *
  27. * @param to 收件人
  28. * @param subject 主题
  29. * @param content 内容
  30. * @param filePath 附件
  31. */
  32. void sendAttachmentsMail(String to, String subject, String content, String filePath);
  33. /**
  34. * 发送模板邮件
  35. * @param to 收件人
  36. * @param subject 主题
  37. * @param fileName 邮件模板文件名称
  38. * @param model 邮件数据载体
  39. */
  40. void sendModelMail(String to, String subject, String fileName, Object model);
  41. }

实现发送邮件工具类

  1. package com.yyg.boot.mail.impl;
  2. import com.yyg.boot.mail.IMailService;
  3. import freemarker.template.Configuration;
  4. import freemarker.template.Template;
  5. import freemarker.template.TemplateException;
  6. import lombok.extern.slf4j.Slf4j;
  7. import org.springframework.beans.factory.annotation.Autowired;
  8. import org.springframework.beans.factory.annotation.Value;
  9. import org.springframework.core.io.ClassPathResource;
  10. import org.springframework.core.io.FileSystemResource;
  11. import org.springframework.mail.SimpleMailMessage;
  12. import org.springframework.mail.javamail.JavaMailSender;
  13. import org.springframework.mail.javamail.MimeMessageHelper;
  14. import org.springframework.stereotype.Service;
  15. import org.springframework.ui.freemarker.FreeMarkerTemplateUtils;
  16. import javax.mail.MessagingException;
  17. import javax.mail.internet.MimeMessage;
  18. import java.io.IOException;
  19. import java.util.Objects;
  20. /**
  21. * @Author 一一哥Sun
  22. * @Date Created in 2020/4/20
  23. * @Description Description
  24. */
  25. @Slf4j
  26. @Service
  27. public class IMailServiceImpl implements IMailService {
  28. /**
  29. * Spring Boot 提供了一个发送邮件的简单抽象,使用的是下面这个接口,这里直接注入即可使用
  30. */
  31. @Autowired
  32. private JavaMailSender mailSender;
  33. @Autowired
  34. private Configuration configuration;
  35. /**
  36. * 配置文件中我的qq邮箱
  37. */
  38. @Value("${spring.mail.from}")
  39. private String from;
  40. /**
  41. * 简单文本邮件
  42. *
  43. * @param to 收件人
  44. * @param subject 主题
  45. * @param content 内容
  46. */
  47. @Override
  48. public void sendSimpleMail(String to, String subject, String content) {
  49. //创建SimpleMailMessage对象
  50. SimpleMailMessage message = new SimpleMailMessage();
  51. //邮件发送人
  52. message.setFrom(from);
  53. //邮件接收人
  54. message.setTo(to);
  55. //邮件主题
  56. message.setSubject(subject);
  57. //邮件内容
  58. message.setText(content);
  59. //发送邮件
  60. mailSender.send(message);
  61. }
  62. /**
  63. * html邮件
  64. *
  65. * @param to 收件人
  66. * @param subject 主题
  67. * @param content 内容
  68. */
  69. @Override
  70. public void sendHtmlMail(String to, String subject, String content) {
  71. //获取MimeMessage对象
  72. MimeMessage message = mailSender.createMimeMessage();
  73. MimeMessageHelper messageHelper;
  74. try {
  75. messageHelper = new MimeMessageHelper(message, true);
  76. //邮件发送人
  77. messageHelper.setFrom(from);
  78. //邮件接收人
  79. messageHelper.setTo(to);
  80. //邮件主题
  81. message.setSubject(subject);
  82. //邮件内容,html格式
  83. messageHelper.setText(content, true);
  84. //发送
  85. mailSender.send(message);
  86. //日志信息
  87. log.info("邮件已经发送...");
  88. } catch (MessagingException e) {
  89. log.error("发送邮件时发生异常!", e);
  90. }
  91. }
  92. /**
  93. * 带附件的邮件
  94. * @param to 收件人
  95. * @param subject 主题
  96. * @param content 内容
  97. * @param filePath 附件
  98. */
  99. @Override
  100. public void sendAttachmentsMail(String to, String subject, String content, String filePath) {
  101. MimeMessage message = mailSender.createMimeMessage();
  102. try {
  103. MimeMessageHelper helper = new MimeMessageHelper(message, true);
  104. helper.setFrom(from);
  105. helper.setTo(to);
  106. helper.setSubject(subject);
  107. helper.setText(content, true);
  108. //FileSystemResource file = new FileSystemResource(new File(filePath));
  109. ClassPathResource resource = new ClassPathResource(filePath);
  110. FileSystemResource file = new FileSystemResource(resource.getFile());
  111. helper.addAttachment(Objects.requireNonNull(file.getFilename()), file);
  112. //可以同时添加多个附件,只需要在这里直接添加第2,第3...附件就行了.
  113. //helper.addAttachment(fileName2, file2);
  114. mailSender.send(message);
  115. //日志信息
  116. log.info("邮件已经发送...");
  117. } catch (MessagingException e) {
  118. log.error("发送邮件时发生异常!", e);
  119. } catch (IOException e) {
  120. e.printStackTrace();
  121. log.error("发送邮件时发生异常!", e);
  122. }
  123. }
  124. @Override
  125. public void sendModelMail(String to, String subject, String fileName, Object model) {
  126. MimeMessage mimeMessage = mailSender.createMimeMessage();
  127. try {
  128. MimeMessageHelper helper = new MimeMessageHelper(mimeMessage, true);
  129. helper.setFrom(from);
  130. helper.setTo(to);
  131. helper.setSubject(subject);
  132. Template template = configuration.getTemplate(fileName);
  133. String html = FreeMarkerTemplateUtils.processTemplateIntoString(template, model);
  134. helper.setText(html, true);
  135. mailSender.send(mimeMessage);
  136. //日志信息
  137. log.info("邮件已经发送...");
  138. } catch (MessagingException e) {
  139. log.error("发送邮件时发生异常!", e);
  140. } catch (TemplateException e) {
  141. e.printStackTrace();
  142. log.error("发送邮件时发生异常!", e);
  143. } catch (IOException e) {
  144. e.printStackTrace();
  145. }
  146. }
  147. }

9. 定义Service及其实现

定义UserService接口

  1. package com.yyg.boot.service;
  2. import com.yyg.boot.entity.User;
  3. /**
  4. * @Author 一一哥Sun
  5. * @Date Created in 2020/4/20
  6. * @Description Description
  7. */
  8. public interface UserService {
  9. /**
  10. * 用户注册,
  11. * @param user
  12. */
  13. void register(User user);
  14. /**
  15. * 根据激活码code查询用户,之后再进行修改状态
  16. */
  17. User checkCode(String code);
  18. /**
  19. * 激活账户,修改用户状态为“1”
  20. */
  21. void updateUserStatus(User user);
  22. /**
  23. * 登录
  24. */
  25. User login(User user);
  26. }

定义UserServiceImpl实现

  1. package com.yyg.boot.service.impl;
  2. import com.yyg.boot.entity.User;
  3. import com.yyg.boot.mail.IMailService;
  4. import com.yyg.boot.repository.UserRepository;
  5. import com.yyg.boot.service.UserService;
  6. import lombok.extern.slf4j.Slf4j;
  7. import org.springframework.beans.factory.annotation.Autowired;
  8. import org.springframework.stereotype.Service;
  9. /**
  10. * @Author 一一哥Sun
  11. * @Date Created in 2020/4/20
  12. * @Description Description
  13. */
  14. @Service
  15. @Slf4j
  16. public class UserServiceImpl implements UserService {
  17. @Autowired
  18. private UserRepository userDao;
  19. /**
  20. * 注入邮件接口
  21. */
  22. @Autowired
  23. private IMailService mailService;
  24. /**
  25. * 用户注册,同时发送一封激活邮件
  26. */
  27. @Override
  28. public void register(User user) {
  29. userDao.save(user);
  30. //获取激活码
  31. String code = user.getCode();
  32. log.warn("code:"+code);
  33. //主题
  34. String subject = "来自一一哥网站的激活邮件";
  35. //user/checkCode?code=code(激活码)是我们点击邮件链接之后根据激活码查询用户,如果存在说明一致,将用户状态修改为“1”激活
  36. //上面的激活码发送到用户注册邮箱
  37. //注意:此处的链接地址,是项目内部地址,如果我们没有正式的服务器地址,暂时无法从qq邮箱中跳转到我们自己项目的激活页面
  38. String context = "<a href=\"http://localhost:8080/user/checkCode?code="+code+"\">激活请点击:"+code+"</a>";
  39. //发送激活邮件
  40. mailService.sendHtmlMail (user.getUserMail(),subject,context);
  41. }
  42. /**
  43. * 根据激活码code进行查询用户,之后再进行修改状态
  44. */
  45. @Override
  46. public User checkCode(String code) {
  47. return userDao.findUserByCode(code);
  48. }
  49. /**
  50. * 激活账户,修改用户状态
  51. */
  52. @Override
  53. public void updateUserStatus(User user) {
  54. userDao.saveAndFlush(user);
  55. }
  56. /**
  57. * 登录
  58. */
  59. @Override
  60. public User login(User user) {
  61. User u = userDao.findByUsernameAndPassword(user.getUsername(),user.getPassword());
  62. if (u !=null){
  63. return u;
  64. }
  65. return null;
  66. }
  67. }

10. 定义跳转到首页面的接口

  1. package com.yyg.boot.web;
  2. import org.springframework.stereotype.Controller;
  3. import org.springframework.web.bind.annotation.RequestMapping;
  4. /**
  5. * @Author 一一哥Sun
  6. * @Date Created in 2020/4/20
  7. * @Description Description
  8. */
  9. @Controller
  10. public class IndexController {
  11. @RequestMapping(value = "/")
  12. public String index(){
  13. return "index";
  14. }
  15. }

11. 定义核心业务接口

  1. package com.yyg.boot.web;
  2. import com.yyg.boot.entity.User;
  3. import com.yyg.boot.service.UserService;
  4. import com.yyg.boot.utils.UUIDUtil;
  5. import org.springframework.beans.factory.annotation.Autowired;
  6. import org.springframework.stereotype.Controller;
  7. import org.springframework.ui.Model;
  8. import org.springframework.web.bind.annotation.*;
  9. /**
  10. * @Author 一一哥Sun
  11. * @Date Created in 2020/4/20
  12. * @Description Description
  13. */
  14. @Controller
  15. @RequestMapping("/user")
  16. public class UserController {
  17. @Autowired
  18. private UserService userService;
  19. /**
  20. * 注册
  21. */
  22. @PostMapping(value = "/registerUser")
  23. public String register(User user){
  24. user.setStatus(0);
  25. String code = UUIDUtil.getUUID();
  26. user.setCode(code);
  27. userService.register(user);
  28. return "success";
  29. }
  30. /**
  31. * 校验邮箱中的code激活账户
  32. * 首先根据激活码code查询用户,之后再把状态修改为"1"
  33. */
  34. @GetMapping(value = "/checkCode")
  35. public String checkCode(String code){
  36. User user = userService.checkCode(code);
  37. //如果用户不等于null,把用户状态修改status=1
  38. if (user !=null){
  39. user.setStatus(1);
  40. //把code验证码清空,已经不需要了
  41. user.setCode("");
  42. userService.updateUserStatus(user);
  43. }
  44. return "login";
  45. }
  46. /**
  47. * 跳转到登录页面
  48. * @return login
  49. */
  50. @GetMapping(value = "/loginPage")
  51. public String login(){
  52. return "login";
  53. }
  54. /**
  55. * 登录
  56. */
  57. @RequestMapping(value = "/loginUser")
  58. public String login(User user){
  59. User u = userService.login(user);
  60. if (u !=null){
  61. return "welcome";
  62. }
  63. return "login";
  64. }
  65. }

12. 创建html页面

index.html页面

  1. <!DOCTYPE html>
  2. <html lang="en" xmlns:th="http://www.w3.org/1999/xhtml">
  3. <head>
  4. <meta charset="UTF-8">
  5. <title>注册</title>
  6. </head>
  7. <body>
  8. <form action="/user/registerUser" method="post">
  9. 用户名:<input type="text" id="username" name="username"/><br>
  10. 密码:<input type="password" id="password" name="password"/><br>
  11. 邮箱:<input type="email" id="usermail" name="userMail"><br>
  12. <input type="submit" value="注册">
  13. </form>
  14. <a href="/user/loginPage">登录</a>
  15. </body>
  16. </html>

login.html页面

  1. <!DOCTYPE html>
  2. <html lang="en">
  3. <head>
  4. <meta charset="UTF-8">
  5. <title>登录</title>
  6. </head>
  7. <body>
  8. <form action="/user/loginUser" method="post">
  9. 用户名:<input type="text" id="username" name="username"/><br>
  10. 密码:<input type="password" id="password" name="password"/><br>
  11. <input type="submit" value="登录">
  12. </form>
  13. </body>
  14. </html>

success.html页面

  1. <!DOCTYPE html>
  2. <html lang="en">
  3. <head>
  4. <meta charset="UTF-8">
  5. <title>注册成功</title>
  6. </head>
  7. <body>
  8. 前往邮箱激活账户
  9. </body>
  10. </html>

welcome.html页面

  1. <!DOCTYPE html>
  2. <html lang="en">
  3. <head>
  4. <meta charset="UTF-8">
  5. <title>欢迎</title>
  6. </head>
  7. <body>
  8. 登录成功
  9. </body>
  10. </html>

13. 创建入口类

  1. package com.yyg.boot;
  2. import org.springframework.boot.SpringApplication;
  3. import org.springframework.boot.autoconfigure.SpringBootApplication;
  4. /**
  5. * @Author 一一哥Sun
  6. * @Date Created in 2020/4/20
  7. * @Description Description
  8. */
  9. @SpringBootApplication
  10. public class CheckMailApplication {
  11. public static void main(String[] args){
  12. SpringApplication.run(CheckMailApplication.class,args);
  13. }
  14. }

14. 完整项目结构

fa0fcd37ab834c98c96163d13f9e8cb9.png

15. 启动程序,进行测试

进入首页面

在首页面里面可以注册一个新用户

c8b6b6737248782836d2defbb34b1eda.png

注册成功

ded2e027176652e271f4fd5fe882c42c.png

可以看到数据库中有了一个新的用户。

22b712a38085e4f7bddcd35bb122b3e9.png

并且邮箱中也收到了激活邮件。

2a9201676eba04d447207c9bffd87352.png

注意:

因为我们的项目并没有上线,激活链接属于项目内部链接,而腾讯邮箱属于外包应用,所以暂时无法实现跳转。等后续项目上线,有了真正的服务器地址,可以把邮件链接改成自己的服务器地址,就可以实现跳转,然后修改自己数据库中用户的状态值了。 咱们的案例中仅做演示,逻辑是没问题的!

发表评论

表情:
评论列表 (有 0 条评论,441人围观)

还没有评论,来说两句吧...

相关阅读

    相关 java 实现注册发送激活邮件+激活

      在很多网站注册的时候,为了验证用户信息的真实合法,往往需要验证用户所填邮件的准确性。形式为:用户注册时填写邮箱,注册完成后,网站会向用户所填邮箱发送一封激活邮件,用户点击激

    相关 springboot实现发送邮件功能

    发送邮件的功能有时在业务中还是需要使用到的,比如订单方面的业务,用户下单后需要给用户发送一个订单相关的邮件;又或者是某些系统在业务层来集成预警功能,出现问题时及时给开发和运维发