SpringBoot整合Java Mail实现发送邮件

SpringBoot整合Java Mail实现发送邮件

实现

引入依赖

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-mail</artifactId>
        </dependency>

发送邮件配置
这里使用qq邮箱发送邮件,需要开启qq邮箱的smtp服务,同时需要拿到授权码。
如果不知道怎么开启服务和获取授权码,可以点击文章末尾的参考文章了解。

spring:
  application:
    name: send-mail
  mail:
    host: smtp.qq.com
    port: 587
    protocol: smtp
    username: xxxxx@qq.com
    password: ybfbprpciavceaig  #password就是授权码
    default-encoding: UTF-8
    test-connection: true
    properties:
      smtp:
        auth: true
        starttls:
          enable: true

邮件发送事件
在需要发送邮件的地方,发布这个事件即可。


public class SendEmailEvent extends ApplicationEvent {


    private String subject;

    private List<String> to;

    private String content;

    private List<File> files;

    private String from;


    public SendEmailEvent(Object source, String subject, List<String> to, String content, List<File> files, String from) {
        super(source);
        this.to =to;
        this.content = content;
        this.files = files;
        this.subject = subject;
        this.from = from;
    }

    public String getSubject() {
        return subject;
    }

    public void setSubject(String subject) {
        this.subject = subject;
    }

    public List<String> getTo() {
        return to;
    }

    public void setTo(List<String> to) {
        this.to = to;
    }

    public String getContent() {
        return content;
    }

    public void setContent(String content) {
        this.content = content;
    }

    public List<File> getFiles() {
        return files;
    }

    public void setFiles(List<File> files) {
        this.files = files;
    }

    public String getFrom() {
        return from;
    }

    public void setFrom(String from) {
        this.from = from;
    }
}

邮件发送事件监听器

循环发送邮件,支持发送附件;使用@Async注解支持异步发送,即使用单独的线程发送邮件

@Component
@EnableAsync
public class SendEmailEventListener implements ApplicationListener<SendEmailEvent> {

    @Autowired
    private JavaMailSender mailSender;

    private Logger logger = LoggerFactory.getLogger(SendEmailEventListener.class);

    @Async
    @Override
    public void onApplicationEvent(SendEmailEvent event) {
        //发送邮件
        String content = event.getContent();
        String subject = event.getSubject();
        List<String> to = event.getTo();
        List<File> files = event.getFiles();
        String from = event.getFrom();

        MimeMessage mimeMessage = mailSender.createMimeMessage();

        try {
            for (String toEmail: to) {
                MimeMessageHelper helper = new MimeMessageHelper(mimeMessage, true);
                //主题
                helper.setSubject(subject);
                //发件人
                helper.setFrom(from);
                //收件人
                helper.setTo(toEmail);
                //内容
                helper.setText(emailContent);
                //附件
                for (File file : files) {
                    helper.addAttachment(file.getName(), new FileDataSource(file));
                }
                mailSender.send(mimeMessage);
            }
        } catch (Exception e) {
            logger.error("发送邮件失败" + e.getMessage() + " " + e.getCause());
        }

    }

}

发送邮件线程池配置

@Configuration
public class MailConfig {

    @Bean
    public TaskExecutor taskExecutor() {
        ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
        executor.setCorePoolSize(2);
        executor.setMaxPoolSize(5);
        executor.initialize();
        return executor;
    }

}

业务调用

    @GetMapping("/send-mail1")
    public String sendMail1() {
        ArrayList<String> emails = new ArrayList<>();
        emails.add("xxxx@163.com");
        String from = "xxxxxxxx@qq.com";
        applicationContext.publishEvent(new SendEmailEvent(
                this, "测试邮件发送", emails, "测试发送邮件", new ArrayList<>(), from));
        return "sendMail1";
    }

发送结果
在这里插入图片描述

集成freemarker,自定义邮件模版发送邮件

引入freemarker的依赖

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-freemarker</artifactId>
        </dependency>

邮件模版配置

spring:
  freemarker:
    template-loader-path: classpath:/templates/
    suffix: .ftl
    charset: UTF-8
    content-type: text/html;charset=utf-8
  datasource:
    driver-class-name: com.mysql.cj.jdbc.Driver
    username: root
    password: root
    url: jdbc:mysql://localhost:3306/foodie_dev?useUnicode=true&characterEncoding=UTF-8&serverTimezone=Asia/Shanghai

freemarker配置类

@Configuration
public class FtlConfiguration {

    @Bean
    public FreeMarkerConfigurer getFreeMarkerConfigurer() {
        FreeMarkerConfigurer configurer = new FreeMarkerConfigurer();
        configurer.setTemplateLoaderPath("classpath:/templates/");
        return configurer;
    }
}

发送代码改造

这里模版中的数据是写死的,可以改造SendEmailEvent传过来

@Component
@EnableAsync
public class SendEmailEventListener implements ApplicationListener<SendEmailEvent> {

    @Autowired
    private JavaMailSender mailSender;

    @Autowired
    private FreeMarkerConfigurer freeMarkerConfigurer;

    private Logger logger = LoggerFactory.getLogger(SendEmailEventListener.class);

    @Async
    @Override
    public void onApplicationEvent(SendEmailEvent event) {
        //发送邮件
        String content = event.getContent();
        String subject = event.getSubject();
        List<String> to = event.getTo();
        List<File> files = event.getFiles();
        String from = event.getFrom();

        MimeMessage mimeMessage = mailSender.createMimeMessage();

        String emailContent = "";
        try {
            for (String toEmail: to) {
                // 加载模板
                Configuration configuration = freeMarkerConfigurer.getConfiguration();
                Template email = configuration.getTemplate("email.ftl");

                Map<String, Object> dataModel = new HashMap<>();
                dataModel.put("title", "Welcome to FreeMarker");
                dataModel.put("message", "Hello, world!");
                emailContent = FreeMarkerTemplateUtils.processTemplateIntoString(email, dataModel);

                MimeMessageHelper helper = new MimeMessageHelper(mimeMessage, true);
                //主题
                helper.setSubject(subject);
                //发件人
                helper.setFrom(from);
                //收件人
                helper.setTo(toEmail);
                //内容,如果使用了ftl则第二个参数设置为true,否则邮件中会是html字符串
                helper.setText(emailContent, true);
                //附件
                for (File file : files) {
                    helper.addAttachment(file.getName(), new FileDataSource(file));
                }

                mailSender.send(mimeMessage);
            }
        } catch (Exception e) {
            logger.error("发送邮件失败" + e.getMessage() + " " + e.getCause());
        }

    }

}

模版如下

<!DOCTYPE html>
<html>
<head>
</head>
<body>
<h1>${title}</h1>

<h1>Today is good day!</h1>

<p>${message}</p>

</body>
</html>

发送结果
在这里插入图片描述

设计邮件记录日志

这里就不给出具体的代码了,表结构如下。
在这里插入图片描述
重试逻辑目前没有写,大家可以考虑加上重试逻辑。同时这个表也没有记录发送的邮件是和哪个业务关联的,也可以考虑记录。

总结

这里的记录发送日志,只能知道是否发送成功;接收方有没有接收到邮件是不能确定的,当然大部分情况下接收方都是可以收到。

参考

  1. 什么是授权码,它又是如何设置?
  2. 什么是 POP3/IMAP/SMTP 服务
Spring Boot提供了`JavaMailSender`来发送邮件,下面是整合Mail发送邮件的步骤: 1. 添加依赖:在`pom.xml`文件中添加`spring-boot-starter-mail`依赖。 2. 配置邮件信息:在`application.yml`文件中配置邮件信息,包括邮件服务器的地址、端口号、发送者的邮箱地址、用户名、密码等。 3. 发送邮件:在需要发送邮件的地方注入`JavaMailSender`,调用其`send()`方法发送邮件。 具体代码如下: 1. 添加依赖 ```xml <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-mail</artifactId> </dependency> ``` 2. 配置邮件信息 ```yml spring: mail: host: smtp.qq.com # 邮件服务器的地址 port: 587 # 邮件服务器的端口号 username: your-email@qq.com # 发送者的邮箱地址 password: your-email-password # 邮箱密码或者授权码 properties: mail.smtp.auth: true mail.smtp.starttls.enable: true mail.smtp.starttls.required: true mail.smtp.ssl.trust: smtp.qq.com # 邮件服务器的地址 ``` 3. 发送邮件 ```java @Service public class MailService { @Autowired private JavaMailSender mailSender; public void sendMail(String to, String subject, String content) { SimpleMailMessage message = new SimpleMailMessage(); message.setTo(to); message.setSubject(subject); message.setText(content); message.setFrom("your-email@qq.com"); // 发送者的邮箱地址 mailSender.send(message); } } ``` 这里使用了`SimpleMailMessage`来设置邮件信息,可以设置收件人、主题、内容等。通过`JavaMailSender`的`send()`方法发送邮件。 需要注意的是,如果邮件服务器需要使用SSL/TLS等加密方式,需要在`application.yml`中设置相应的属性。另外,如果使用的是第三方邮件服务商,可能需要开启SMTP服务和获取授权码等操作。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值