springboot简单实现邮件功能

简单实现发送邮件的小功能

1.准备

需要一个邮箱,并开启POP3/IMAP/SMTP服务。

以QQ邮箱为例,邮箱设置-账户,就能开启对应的服务,并获取授权码。

springboot简单实现邮件功能

2.引入依赖
<!-- 邮件依赖,版本由springboot管理 -->
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-mail</artifactId>
</dependency>
3.在application.yml配置文件中,配置相应的参数
spring:
  mail:
    host: smtp.qq.com #QQ的发送邮件服务器
    username: 邮箱
    password: 授权码
4.编写一个工具类
@Data
@Slf4j
@Component
public class MailUtil {

    //注入邮件服务
    @Autowired
    private JavaMailSenderImpl mailSender;
    //谁来发
    @Value("${spring.mail.username}")
    private String from;

    /**
     * 发送简单邮件
     * @param email 发给谁
     * @param subject 邮件主题
     * @param text 邮件内容
     */
    public void sendSimpleMail(String email,String subject,String text){
        try {
            SimpleMailMessage simpleMailMessage = new SimpleMailMessage();
            simpleMailMessage.setFrom(from);
            simpleMailMessage.setTo(email);
            simpleMailMessage.setSubject(subject);
            simpleMailMessage.setText(text);
            mailSender.send(simpleMailMessage);
        }catch (Exception e){
            log.error("发送失败!",e);
            throw new RuntimeException(e);
        }
    }
}
5.编写业务方法,以发送验证码为例
@Async("myExecutor"
public void sendCodeMail(String email) {
    //六位随机数的验证码
    String code = CodeUtil.randomCode(6);
    //邮件主题
    String subject = "验证码";
    //邮件内容
    String text = "验证码:" + code +",10分钟之内有效。";

    Map<String,Object> map = new HashMap<>(2);
    map.put("code",code);
    map.put("createTime",System.currentTimeMillis());

    //将验证码缓存进redis中,并设置过期时间,方便后续做校验
    redisTemplate.opsForHash().putAll(ConstantUtil.USER_MAIL_CODE + email,map);
    redisTemplate.expire(ConstantUtil.USER_MAIL_CODE + email,10,TimeUnit.MINUTES);

    mailUtil.sendSimpleMail(email,subject,text);
}

/**
 * 说明:由于发送邮件,可能会比较耗时间,所以需要异步调用。
 * 这里的处理方式是,配置一个线程池,通过@Async("myExecutor"),另启线程调用。
 * 偷懒的话,可以在启动类添加注解@EnableAsync,再在方法上用注解@Async,也可以开启异步调用。
 */
 
/**
 * 限制一分钟内只能发一条,避免恶意攻击
 */
public boolean checkSendToLegal(String email) {
        //利用正则表达式,验证邮箱是否符合邮箱的格式
        if(!email.matches("^\w+([-+.]\w+)*@\w+([-.]\w+)*\.\w+([-.]\w+)*$")){
            return true;
        }
        Long now = System.currentTimeMillis();
        Long codeCreateTime =(Long)redisTemplate.opsForHash().get(ConstantUtil.USER_MAIL_CODE + email, "createTime");
        return codeCreateTime != null && now - codeCreateTime < 60000;
}
6.编写测试方法
@Test
public void sendCodeMail(){
    //发给谁
    String email = "";
    //限制一分钟内只能发一条,避免恶意攻击
    if(mailService.checkSendToLegal(email)){
        log.error("操作过于频繁,请一分钟后再试!");
    }
    mailService.sendCodeMail(email);
}

效果截图:

springboot简单实现邮件功能

7.发送复杂邮件,以给邮箱发送激活链接为例
  • 在工具类中添加如下方法
/**
 * 发送定制邮件
 * @param template 模板,这个代码就不贴了,很简单
 */
public void sendMimeMail(MailTemplate template){
  try {
      //true表示支持复杂类型
      MimeMessageHelper messageHelper = new MimeMessageHelper(mailSender.createMimeMessage(), true);
      //邮件发信人
      messageHelper.setFrom(from);
      //邮件收信人
      if (!ObjectUtils.isEmpty(template.getTo())) {
          messageHelper.setTo(template.getTo());
      }
      //给谁回复
      if(StringUtils.hasText(template.getReplyTo())){
          messageHelper.setReplyTo(template.getReplyTo());
      }
      //邮件主题
      if (StringUtils.hasText(template.getSubject())) {
          messageHelper.setSubject(template.getSubject());
      }
      //邮件内容,true时,显示html代码效果,默认为false
      if (StringUtils.hasText(template.getText())) {
          messageHelper.setText(template.getText(),template.isHtml());
      }
      //抄送
      if (!ObjectUtils.isEmpty(template.getCc())) {
          messageHelper.setCc(template.getCc());
      }
      //密送
      if (!ObjectUtils.isEmpty(template.getBcc())) {
          messageHelper.setCc(template.getBcc());
      }
      //添加邮件附件
      if (!CollectionUtils.isEmpty(template.getMultipartFiles())) {
          for (MultipartFile multipartFile : template.getMultipartFiles()) {
              messageHelper.addAttachment(Objects.requireNonNull(multipartFile.getOriginalFilename()), multipartFile);
          }
      }
      //发送时间
      if (!ObjectUtils.isEmpty(template.getSentDate())) {
          template.setSentDate(new Date());
          messageHelper.setSentDate(template.getSentDate());
      }
      //正式发送邮件
      mailSender.send(messageHelper.getMimeMessage());
      template.setStatus("1");
  } catch (Exception e) {
      log.error("发送失败!",e);
      throw new RuntimeException(e);
  }
}
  • 添加一个发送邮件的业务方法
@Async("myExecutor")
public void sendLinkMail(String email) {
    //用email生产token串
    String token = JWTUtil.createToken(email);
    String subject = "账户激活";
    String text = "<!DOCTYPE html><html><head></head>" +
            "<body>" +
            "<h1>点击下面的按钮即可激活账户</h1>n" +
            "<h3><a href='http://localhost:8080/test/verify_email?token="+token+"'>立即激活</a></h3>" +
            "</body>" +
            "</html>";

    MailTemplate mailTemplate = new MailTemplate();
    mailTemplate.setTo(email);
    mailTemplate.setSentDate(new Date());
    mailTemplate.setSubject(subject);
    mailTemplate.setText(text);
    mailTemplate.setHtml(true);
    //缓存token信息,email作为key
    redisTemplate.opsForValue().set(ConstantUtil.USER_MAIL_LINK + email,token,7,TimeUnit.DAYS);
    mailUtil.sendMimeMail(mailTemplate);
}

/**
 * 根据token获取email信息,校验缓存中是否存在
 */
public boolean verifyLink(String token) {
    String email = JWTUtil.getUsernameByToken(token);
    Object o = redisTemplate.opsForValue().get(ConstantUtil.USER_MAIL_LINK + email);
    return ObjectUtils.isEmpty(o);
}
  • 添加相关的模拟接口
/**
 * 模拟 给邮箱发送激活链接
 * @param email
 * @return
 */
@GetMapping("sendLink")
public R sendLinkMail(@RequestParam String email){
    mailService.sendLinkMail(email);
    return R.ok("success");
}

/**
 * 激活链接url
 * @param token
 * @return
 */
@GetMapping("verify_email")
public R verifyEmail(@RequestParam String token){
    if(mailService.verifyLink(token)){
        return R.failed("激活失败,认证信息已经失效!");
    }
    // todo 激活账户相关业务

    // todo 最后,删除对应的缓存
    
    return R.ok("success");
}

效果截图:

springboot简单实现邮件功能


原文始发于微信公众号(勤劳的懒猫):springboot简单实现邮件功能

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。

文章由极客之音整理,本文链接:https://www.bmabk.com/index.php/post/256494.html

(0)
Java光头强的头像Java光头强

相关推荐

发表回复

登录后才能评论
极客之音——专业性很强的中文编程技术网站,欢迎收藏到浏览器,订阅我们!