SpringBoot整合Mail实现邮件发送

本文最后更新于2024.04.23-04:53,某些文章具有时效性,若有错误或已失效,请在下方留言或联系涛哥

前言

在这个互联网时代,QQ,163等邮件的发送越发普遍!!!

比如:系统消息的推送、系统注册用户消息推送、重置密码等等都会使用到消息推送

还有就是我们日常的邮件功能

开发技术

  • SpringBoot
  • Mail
  • Swagger
  • lombok

实际案列

1、在pom.xml引入mail依赖

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-mail</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <!--swagger-->
        <dependency>
            <groupId>io.springfox</groupId>
            <artifactId>springfox-boot-starter</artifactId>
            <version>3.0.0</version>
        </dependency>
        <dependency>
            <groupId>com.github.xiaoymin</groupId>
            <artifactId>knife4j-spring-boot-starter</artifactId>
            <version>3.0.3</version>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-devtools</artifactId>
            <scope>runtime</scope>
            <optional>true</optional>
        </dependency>
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <optional>true</optional>
        </dependency>

2、配置yml

server:
  port: 8080
spring:
  mvc:
    path match:
      matching-strategy: ant_path_matcher
  mail:
    host: smtp.qq.com
    port: 465 # smtp-587/smtps-465
    username: 2484202301@qq.com
    password: vnlnoichgqenecdf
    default-encoding: UTF-8
    protocol: smtps
    properties:
      mail:
        smtp:
          auth: true
          socketFactoryClass: javax.net.ssl.SSLSocketFactory
          starttls:
            enable: true
            required: true
          ssl: true
        debug: true
file:
  upload:
    path: F:\\软件开发\\项目\\SpringBoot\\SpringBoot_Mail\\file\\

 

3、配置Swaggerconfig文件

@Configuration
@EnableSwagger2
public class SwaggerConfig {

    /**
     * 创建API应用
     * apiInfo() 增加API相关信息
     * 通过select()函数返回一个ApiSelectorBuilder实例,用来控制哪些接口暴露给Swagger来展现,
     * 本例采用指定扫描的包路径来定义指定要建立API的目录。
     *
     * @return
     */
    @Bean
    public Docket restApi() {
        return new Docket(DocumentationType.SWAGGER_2)
                .groupName("标准接口")
                .apiInfo(apiInfo("CRUD管理接口文档", "1.0"))
                .useDefaultResponseMessages(true)
                .forCodeGeneration(false)
                .select()
                .apis(RequestHandlerSelectors.basePackage("com.example.mail.web"))
                .paths(PathSelectors.any())
                .build();
    }

    /**
     * 创建该API的基本信息(这些基本信息会展现在文档页面中)
     * 访问地址:http://ip:port/doc.html
     *
     * @return
     */
    private ApiInfo apiInfo(String title, String version) {
        return new ApiInfoBuilder()
                .title(title)
                .description("SpringBoot整合mail starter")
                .termsOfServiceUrl("https://ltbk.net")
                .contact(new Contact("涛哥", "https://ltbk.net", "taoge@163.com"))
                .version(version)
                .build();
    }
}

4、创建mail实体类

package com.example.mail.entity;

import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import org.springframework.util.Assert;
import org.springframework.web.multipart.MultipartFile;

/**
 * @Program: SpringBoot
 * @ClassName Mail
 * @Author: liutao
 * @Description: 邮件实体类
 * @Create: 2023-08-25 22:09
 * @Version 1.0
 **/

@Data
@AllArgsConstructor
@NoArgsConstructor
public class Mail {
    private String from;
    private String[] to;
    private String subject;
    private String message;
    private MultipartFile[] attachments;
}

5, 创建异步任务管理器 配合 @EnableAsync和@Async

@EnableAsync加在启动类上

package com.example.mail.manager;

import lombok.extern.slf4j.Slf4j;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Component;

import javax.annotation.PostConstruct;
import java.util.concurrent.CompletableFuture;

/**
 * @Program: SpringBoot
 * @ClassName AsyncTaskManager
 * @Author: liutao
 * @Description: 异步任务管理器
 * @Create: 2023-11-26 19:55
 * @Version 1.0
 **/
@Slf4j
@Component
public class AsyncTaskManager {

    @PostConstruct
    public void init() {
        log.info("异步任务管理器启动。。。");
    }

    /***
     * @Param: runnable
     * @Description: 异步执行任务
     **/
    @Async
    public void execute(Runnable runnable) {
        CompletableFuture.runAsync(runnable);
    }

}

6,发送接口

package com.example.mail.service;

import com.example.mail.entity.Mail;

import javax.mail.MessagingException;

/**
 * @Program: SpringBoot
 * @ClassName MainService
 * @Author: liutao
 * @Description: 对接mail接口层
 * @Create: 2023-08-25 21:35
 * @Version 1.0
 **/
public interface MailService {
    void sendText(Mail mail);

    void sendHtml(Mail mail) throws MessagingException;

    void sendAttachment(Mail mail, String... attachments);
}
package com.example.mail.service.impl;

import com.example.mail.entity.Mail;
import com.example.mail.manager.AsyncTaskManager;
import com.example.mail.service.MailService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.io.FileSystemResource;
import org.springframework.mail.SimpleMailMessage;
import org.springframework.mail.javamail.JavaMailSender;
import org.springframework.mail.javamail.MimeMessageHelper;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;

import javax.mail.MessagingException;
import javax.mail.internet.MimeMessage;
import java.io.File;
import java.util.Objects;

/**
 * @Program: SpringBoot
 * @ClassName MailServiceImpl
 * @Author: liutao
 * @Description: MailService实现类
 * @Create: 2023-08-25 21:54
 * @Version 1.0
 **/
@Slf4j
@Service
public class MailServiceImpl implements MailService {
    @Autowired
    private JavaMailSender sender;
    @Autowired
    private AsyncTaskManager asyncTaskManager;

    /**
     * 发送文本邮件
     *
     * @param mail
     */
    @Async
    @Override
    public void sendText(Mail mail) {
        SimpleMailMessage message = new SimpleMailMessage();
        message.setFrom(mail.getFrom());
        message.setTo(mail.getTo());
        message.setSubject(mail.getSubject());
        message.setText(mail.getMessage());
        log.info("Sent mail{}", message);
        try {
            asyncTaskManager.execute(() -> {
                sender.send(message);
            });
        } catch (Exception e) {
            log.info("Send text mail failed: " + e.getMessage());
        }

        log.info("Send text mail successfully");
    }

    /**
     * 发送html邮件
     *
     * @param mail
     */
    @Async
    @Override
    public void sendHtml(Mail mail) {
        MimeMessage mimeMessage = sender.createMimeMessage();
        try {
            MimeMessageHelper mimeMessageHelper = new MimeMessageHelper(mimeMessage, true);
            mimeMessageHelper.setFrom(mail.getFrom());
            mimeMessageHelper.setTo(mail.getTo());
            mimeMessageHelper.setSubject(mail.getSubject());
            mimeMessageHelper.setText(mail.getMessage(), true);
            asyncTaskManager.execute(() -> {
                sender.send(mimeMessage);
            });
            log.info("Send html mail successfully");
        } catch (MessagingException e) {
            log.info("Send html mail failed: " + e.getMessage());
            throw new RuntimeException(e);
        }
    }

    /**
     * 发送带附件的邮件
     *
     * @param mail
     * @param attachments
     */
    @Async
    @Override
    public void sendAttachment(Mail mail, String... attachments) {
        MimeMessage mimeMessage = sender.createMimeMessage();
        try {
            MimeMessageHelper mimeMessageHelper = new MimeMessageHelper(mimeMessage, true);
            mimeMessageHelper.setFrom(mail.getFrom());
            mimeMessageHelper.setTo(mail.getTo());
            mimeMessageHelper.setSubject(mail.getSubject());
            mimeMessageHelper.setText(mail.getMessage(), true);
            for (String attachment : attachments) {
                FileSystemResource file = new FileSystemResource(new File(attachment));
                mimeMessageHelper.addAttachment(Objects.requireNonNull(file.getFilename()), file);
            }
            asyncTaskManager.execute(() -> {
                sender.send(mimeMessage);
            });
            log.info("Send attachment mail successfully");

        } catch (MessagingException e) {
            log.info("Send attachment mail failed: " + e.getMessage());
            throw new RuntimeException(e);
        }
    }
}

7,api接口

package com.example.mail.web;

import com.example.mail.entity.Mail;
import com.example.mail.service.MailService;
import io.swagger.annotations.Api;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RestController;

import javax.mail.MessagingException;
import java.io.File;
import java.io.IOException;

/**
 * @Program: SpringBoot
 * @ClassName MailController
 * @Author: liutao
 * @Description: web
 * @Create: 2023-08-25 22:21
 * @Version 1.0
 **/
@Slf4j
@Api(tags = "邮件发送")
@RestController
public class MailController {
    @Autowired
    private MailService mailService;
    @Value("${spring.mail.username}")
    private String from;
    @Value("${file.upload.path}")
    private String uploadPath;

    @PostMapping("/sendText")
    String sendText(@RequestBody Mail mail) {
        log.info("from {} Mail{}", from, mail);
        mail.setFrom(from);
        mailService.sendText(mail);
        return "200";
    }

    @PostMapping("/sendHtml")
    String sendHtml(@RequestBody Mail mail) {
        mail.setFrom(from);
        try {
            mailService.sendHtml(mail);
        } catch (MessagingException e) {
            throw new RuntimeException(e);
        }
        return "ok";
    }

    @PostMapping("/sendAttachment")
    String sendAttachment(@ModelAttribute Mail mail) throws IOException {
        System.out.println(mail);
        String[] attachments = new String[mail.getAttachments().length];
        for (int i = 0; i < attachments.length; i++) {
            mail.getAttachments()[i].transferTo(new File(uploadPath + mail.getAttachments()[i].getOriginalFilename()));
            attachments[i] = uploadPath + mail.getAttachments()[i].getOriginalFilename();
        }
        mail.setFrom(from);
        mailService.sendAttachment(mail, attachments);
        return "ok";
    }
}

测试结果

结尾

到这里我们的整合就结束了!!

喜欢欢迎点赞、关注、收藏三连!!

see you!!

阅读剩余
THE END