当前位置:   article > 正文

Springboot发送邮箱验证码(QQ,163)_springboot邮箱验证码

springboot邮箱验证码
--下面以QQ邮箱为列,163与自建邮箱同理,后附有异步发送优化
实现思路
1.使用Freemaker生成邮箱模版
2.发送邮箱为异步发送,使用SpringBoot的线程池
  1. 邮箱开启smtp服务
  • 点击开启

  • 根据要求发送短信

  • 发送完毕点击我已发送,会生成授权码,!!!记住授权码

  1. 引入SpringBoot-mail和Freemaker的依赖
  1. <dependency>
  2. <groupId>org.springframework.boot</groupId>
  3. <artifactId>spring-boot-starter-mail</artifactId>
  4. </dependency>
  5. <dependency>
  6. <groupId>org.springframework.boot</groupId>
  7. <artifactId>spring-boot-starter-freemarker</artifactId>
  8. <version>2.4.2</version>
  9. </dependency>
!!!Freemaker用于生成邮箱模版
  1. 设置模版
  • 在resources目录下创建模版文件register_email.ftl

  • register_email.ftl内容

${email}和${verifyCode}为需要替换的参数
  1. <!DOCTYPE html>
  2. <html>
  3. <head>
  4. <meta charset="UTF-8">
  5. <title>注册验证码</title>
  6. </head>
  7. <body>
  8. <div>
  9. <div>${email},你好!</div>
  10. <br/>
  11. <div>&emsp;&emsp;您好,您的验证码为:&nbsp;<span style="color:blue;font-size: 20px;font-weight: 700;">${verifyCode}</span>
  12. &nbsp;验证码10分钟内有效,请在时限内完成注册。
  13. 期待您的加入!</div>
  14. <br/>
  15. <div>XXX有限公司</div>
  16. <br/>
  17. <div>谢谢!</div>
  18. </div>
  19. </body>
  20. </html>
  1. 在application.yml文件中配置邮箱参数
  1. spring:
  2. mail:
  3. # 配置 SMTP 服务器地址
  4. host: mail.qq.net
  5. # 发送者邮箱
  6. username: xxxxx@qq.com
  7. # 配置密码,注意不是真正的密码,而是刚刚申请到的授权码
  8. password: xxxxxxxxxxxxx
  9. # 端口号465或587
  10. port: 465
  11. #默认的邮件编码为UTF-8
  12. default-encoding: UTF-8
  13. protocol: smtps
  • 创建EmailUtils.java文件

  1. package com.lnsk.common.utils;
  2. import com.lnsk.common.constant.Constants;
  3. import freemarker.cache.ClassTemplateLoader;
  4. import freemarker.template.Configuration;
  5. import freemarker.template.Template;
  6. import freemarker.template.TemplateException;
  7. import lombok.extern.slf4j.Slf4j;
  8. import org.springframework.beans.factory.annotation.Value;
  9. import org.springframework.mail.javamail.JavaMailSenderImpl;
  10. import org.springframework.mail.javamail.MimeMessageHelper;
  11. import org.springframework.scheduling.annotation.Async;
  12. import org.springframework.stereotype.Component;
  13. import javax.mail.MessagingException;
  14. import javax.mail.internet.MimeMessage;
  15. import java.io.IOException;
  16. import java.io.StringWriter;
  17. import java.nio.charset.Charset;
  18. import java.util.Date;
  19. import java.util.Map;
  20. import java.util.Properties;
  21. /**
  22. * 邮箱工具类
  23. * @author haiven
  24. *
  25. */
  26. @Slf4j
  27. @Component
  28. public class EmailUtils {
  29. //发件人邮箱
  30. @Value("${spring.mail.username}")
  31. private String username;
  32. //发件人密码
  33. @Value("${spring.mail.password}")
  34. private String password;
  35. //发件人host
  36. @Value("${spring.mail.host}")
  37. private String host;
  38. //发件人端口
  39. @Value("${spring.mail.port}")
  40. private String port;
  41. //邮件模板名
  42. private static final String TEMP_FILE_NAME = "register_email.ftl";
  43. /**
  44. * 发送邮件
  45. * @param subject 邮件主题
  46. * @param content 邮内容
  47. * @param to 邮件接收人
  48. * @throws MessagingException
  49. */
  50. @Async("verifyThreadPool")
  51. public void sendEmail(String subject,String content,String to) throws MessagingException {
  52. JavaMailSenderImpl javaMailSender = new JavaMailSenderImpl();
  53. javaMailSender.setPort(port);
  54. javaMailSender.setUsername(username);
  55. javaMailSender.setPassword(password);
  56. javaMailSender.setHost(host);
  57. javaMailSender.setDefaultEncoding(Constants.UTF8);
  58. Properties properties = new Properties();
  59. properties.setProperty("mail.smtp.socketFactory.port", port);
  60. properties.setProperty("mail.smtp.socketFactory.class", "javax.net.ssl.SSLSocketFactory");
  61. javaMailSender.setJavaMailProperties(properties);
  62. MimeMessage mailMessage=javaMailSender.createMimeMessage();
  63. //需要借助Helper类
  64. MimeMessageHelper helper=new MimeMessageHelper(mailMessage);
  65. log.debug("Register send email:" + username );
  66. helper.setFrom(username);
  67. helper.setTo(to);
  68. //helper.setBcc("密送人");
  69. helper.setSubject(subject);
  70. helper.setSentDate(new Date());//发送时间
  71. //第一个参数要发送的内容,第二个参数是不是Html格式。
  72. helper.setText(content,true);
  73. javaMailSender.send(mailMessage);
  74. }
  75. /**
  76. * 加载邮件模板
  77. * @param email & verifyCode 邮件模板参数
  78. * @return
  79. * @throws IOException
  80. * @throws TemplateException
  81. */
  82. public static String loadEmailContent(String email,String verifyCode) throws IOException, TemplateException {
  83. Map<String,String> dataMap = new HashMap<>();
  84.         dataMap.put("email",email);
  85.         dataMap.put("verifyCode",verifyCode);
  86.         //初始化模板
  87. Configuration configuration = new Configuration(Configuration.DEFAULT_INCOMPATIBLE_IMPROVEMENTS);
  88. configuration.setDefaultEncoding(Charset.forName("UTF-8").name());
  89. //设置模板文件路径
  90. configuration.setTemplateLoader(new ClassTemplateLoader(EmailUtils.class,"/templates/"));
  91. //获取模板
  92. Template template = configuration.getTemplate(TEMP_FILE_NAME);
  93. //输出位置 这里用字符串输出,如果要输出文件自行替换
  94. StringWriter writer = new StringWriter();
  95. template.process(dataMap, writer);
  96. StringBuffer buffer = writer.getBuffer();
  97. return buffer.toString();
  98. }
  99. }
loadEmailContent方法为加载邮箱内容方法,参数为register_email.ftl中的email和verifyCode两个参数
  • 创建测试类,测试发送邮箱

  1. package com.lnsk.order.controller;
  2. import com.lnsk.common.utils.EmailUtils;
  3. import freemarker.template.TemplateException;
  4. import org.springframework.beans.factory.annotation.Autowired;
  5. import org.springframework.web.bind.annotation.GetMapping;
  6. import org.springframework.web.bind.annotation.RequestParam;
  7. import org.springframework.web.bind.annotation.RestController;
  8. import javax.mail.MessagingException;
  9. import java.io.IOException;
  10. @RestController
  11. public class TestUtils {
  12. @Autowired
  13. EmailUtils emailUtils;
  14.     //邮件主题
  15. private static final String SUBJECT = "测试邮箱";
  16. @GetMapping("/getVerifyCode")
  17. public String getVerifyCode(@RequestParam String email) throws TemplateException, IOException, MessagingException {
  18. String content = EmailUtils.loadEmailContent(email, getCode());
  19. emailUtils.sendEmail(SUBJECT,content,email);
  20. return "OK";
  21. }
  22. /**
  23. * 获取邮箱验证码
  24. * @return
  25. */
  26. public String getCode(){
  27. return String.valueOf((int)((Math.random() * 9 + 1) * Math.pow(10,5)));
  28. }
  29. }
  • 调用接口

  • 查看邮箱,看是否发送成功

5. 代码优化
将邮箱改为异步发送,使用Spring的线程池

定义线程池配置类LnskThreadPoolConfig.java

  1. package com.lnsk.common.config;
  2. import org.springframework.context.annotation.Bean;
  3. import org.springframework.context.annotation.Configuration;
  4. import org.springframework.scheduling.annotation.EnableAsync;
  5. import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
  6. import java.util.concurrent.ThreadPoolExecutor;
  7. @Configuration
  8. @EnableAsync
  9. public class LnskThreadPoolConfig {
  10. /**
  11. * 核心线程数
  12. */
  13. private static final int CORE_POOL_SIZE = 10;
  14. /**
  15. * 最大线程数
  16. */
  17. private static final int MAX_POOL_SIZE = 20;
  18. /**
  19. * 允许线程空闲时间 默认为秒
  20. */
  21. private static final int KEEP_ALIVE_SECONDS = 60;
  22. /**
  23. * 缓冲队列
  24. */
  25. private static final int QUEUE_SIZE = 40;
  26. /**
  27. * 线程命名
  28. */
  29. private static final String THREAD_NAME_PRE = "Verify thread-";
  30.     //线程池名称verifyThreadPool
  31. @Bean("verifyThreadPool")
  32. public ThreadPoolTaskExecutor getVerifyThreadPool(){
  33. ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
  34. executor.setCorePoolSize(CORE_POOL_SIZE);
  35. executor.setMaxPoolSize(MAX_POOL_SIZE);
  36. executor.setQueueCapacity(QUEUE_SIZE);
  37. executor.setKeepAliveSeconds(KEEP_ALIVE_SECONDS);
  38. executor.setThreadNamePrefix(THREAD_NAME_PRE);
  39. // 线程池对拒绝任务的处理策略(抛出异常)
  40. executor.setRejectedExecutionHandler(new ThreadPoolExecutor.AbortPolicy());
  41. // 初始化
  42. executor.initialize();
  43. return executor;
  44. }
  45. }
  • 在发送验证码的方法上加入@Async("verifyThreadPool")注解,并交给Spring容器管理

!!!该注解方法不能修饰静态方法

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/花生_TL007/article/detail/686348
推荐阅读
相关标签
  

闽ICP备14008679号