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-mailmail:host: smtp.qq.comport: 587protocol: smtpusername: xxxxx@qq.compassword: ybfbprpciavceaig  #password就是授权码default-encoding: UTF-8test-connection: trueproperties:smtp:auth: truestarttls: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> {@Autowiredprivate JavaMailSender mailSender;private Logger logger = LoggerFactory.getLogger(SendEmailEventListener.class);@Async@Overridepublic 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 {@Beanpublic 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: .ftlcharset: UTF-8content-type: text/html;charset=utf-8datasource:driver-class-name: com.mysql.cj.jdbc.Driverusername: rootpassword: rooturl: jdbc:mysql://localhost:3306/foodie_dev?useUnicode=true&characterEncoding=UTF-8&serverTimezone=Asia/Shanghai

freemarker配置类

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

发送代码改造

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

@Component
@EnableAsync
public class SendEmailEventListener implements ApplicationListener<SendEmailEvent> {@Autowiredprivate JavaMailSender mailSender;@Autowiredprivate FreeMarkerConfigurer freeMarkerConfigurer;private Logger logger = LoggerFactory.getLogger(SendEmailEventListener.class);@Async@Overridepublic 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 服务

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/diannao/46058.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Leetcode3200. 三角形的最大高度

Every day a Leetcode 题目来源&#xff1a;3200. 三角形的最大高度 解法1&#xff1a;模拟 枚举第一行是红色还是蓝色&#xff0c;再按题意模拟即可。 代码&#xff1a; /** lc appleetcode.cn id3200 langcpp** [3200] 三角形的最大高度*/// lc codestart class Solutio…

java.sql.SQLException: Before start of result set

情况描述&#xff0c;在通过JDBC连接数据库时&#xff0c;想直接判断获取的值是否存在&#xff0c;运行时报错。 翻译&#xff1a; 在开始结果集之前 报错截图 解决问题的方法&#xff1a;对结果集ResultSet进行操作之前&#xff0c;一定要先用ResultSet.next()将指针移动至…

RAG 效果提升的最后一步—— 微调LLM

如果说&#xff0c;rerank能够让RAG的效果实现百尺竿头更进一步&#xff0c;那么LLM微调应该是RAG效果提升的最后一步。 把召回的数据&#xff0c;经过粗排&#xff0c;重排序后&#xff0c;送给模型&#xff0c;由模型最后总结答案。LLM的确已经是RAG的最后一步了。 这里还是会…

C#可空类型与数组

文章目录 可空类型NULL合并运算符&#xff08;??&#xff09;数组数组声明数组初始化数组赋值数组访问多维数组交错数组数组类数组类的常用属性数组类的常用方法 可空类型 C#提供了一种特殊的数据类型&#xff0c;nullable类型&#xff08;可空类型&#xff09;&#xff0c;可…

<数据集>夜间车辆识别数据集<目标检测>

数据集格式&#xff1a;VOCYOLO格式 图片数量&#xff1a;5000张 标注数量(xml文件个数)&#xff1a;5000 标注数量(txt文件个数)&#xff1a;5000 标注类别数&#xff1a;8 标注类别名称&#xff1a;[car, pedestrian, traffic light, traffic sign, bicycle, bus, truck…

vue学习day08-v-model详解、sync修饰符、ref和$refs获取dom组件、Vue异步更新和$nextTick

25、v-model详解 &#xff08;1&#xff09;v-model原理 1&#xff09;原理: v-model本质上是一个语法糖&#xff0c;比如&#xff1a;在应用于输入框时&#xff0c;就是value属性与input事件的合写。 2&#xff09;作用 ①数据变&#xff0c;视图变 ②视图变&#xff0c…

wordpress制作主题步骤

WordPress主题的制作是一个涉及多个步骤的过程&#xff0c;旨在控制网站的外观、布局和功能。以下是一个详细的WordPress主题制作指南&#xff1a; 一、准备工作 安装WordPress&#xff1a;首先&#xff0c;确保你已经在你的服务器上安装了WordPress。WordPress可以从其官方网…

短链接服务Octopus-搭建实战

[WARNING] The POM for cn.throwx:octopus-contract:jar:1.0-SNAPSHOT is missing, no dependency information available 解决方案&#xff1a; cd octopus-contract/ mvn install -------------- ➜ octopus-server git:(master) ✗ mkdir -p /data/log-center/octopus/s…

DockerCompose介绍,安装,使用

DockerCompose 1、Compose介绍 将单机服务-通过Dockerfile 构建为镜像 -docker run 成为一个服务 user 8080 net 7000 pay 8181 admin 5000 监控 .... docker run 单机版、一个个容器启动和停止问题&#xff1a; 前面我们使用Docker的时候&#xff0c;定义 Dockerfil…

Lottery 分布式抽奖(个人向记录总结)

1.搭建&#xff08;DDDRPC&#xff09;架构 DDD——微服务架构&#xff08;微服务是对系统拆分的方式&#xff09; &#xff08;Domain-Driven Design 领域驱动设计&#xff09; DDD与MVC同属微服务架构 是由Eric Evans最先提出&#xff0c;目的是对软件所涉及到的领域进行建…

mysql笔记(表导出文件,文件导入表)

遇见权限问题1: cat /etc/my.cnf加入[mysqld] secure_file_priv ""遇见目录错误2:因为 MySQL 服务器没有权限在根目录下创建文件。你可以尝试将文件导出到一个 MySQL 服务器有权限写入的目录下&#xff0c;例如 MySQL 数据目录或 /tmp目录。sudo chmod 755 /path/to…

开源科学工程技术软件

目录 0 参考链接 1 Silx 2 Klampt 3 参数化三维3D软件Dune 3D 4 GPS日志文件查看器GPXSee 5 三维3D软件Chili3D 6 集成电路设计软件XicTools 7 天文学软件Cosmonium 8 计算流体力学软件FluidX3D 9 点云处理软件CloudCompare 10 野外火灾建模软件WindNinja 11 电子设…

.NET MAUI开源架构_2.什么是 .NET MAUI?

1.什么是.NET MAUI&#xff1f; .NET 多平台应用 UI (.NET MAUI) 是一个跨平台框架&#xff0c;用于使用 C# 和 XAML 创建本机移动和桌面应用。使用 .NET MAUI&#xff0c;可从单个共享代码库开发可在 Android、iOS、macOS 和 Windows 上运行的应用。 .NET MAUI 是一款…

使机器人在执行任务时更加稳定

为了使机器人在执行任务时更加稳定&#xff0c;调整参数时需要考虑多个因素&#xff0c;如步态、速度、角度等。这些参数的调整需要基于实际环境、任务需求和机器人自身的物理特性。以下是一些具体的调整建议&#xff1a; 1. 调整步态和步高 gait_type3; step_height0.03;步态…

iOS热门面试题(四)

问题一&#xff1a;请详细解释iOS中的Core Data框架&#xff0c;包括它的工作原理、优势、以及在实际项目中的应用场景。 Core Data框架概述&#xff1a; Core Data是iOS和macOS开发中一个强大的数据持久化框架&#xff0c;它允许开发者以面向对象的方式管理应用数据。Core D…

pytorch中一些最基本函数和类

1.Tensor操作 Tensor是PyTorch中最基本的数据结构&#xff0c;类似于NumPy的数组&#xff0c;但可以在GPU上运行加速计算。 示例&#xff1a;创建和操作Tensor import torch# 创建一个零填充的Tensor x torch.zeros(3, 3) print(x)# 加法操作 y torch.ones(3, 3) z x y pr…

【学习笔记】无人机(UAV)在3GPP系统中的增强支持(三)-机上无线电接入节点无人机

引言 本文是3GPP TR 22.829 V17.1.0技术报告&#xff0c;专注于无人机&#xff08;UAV&#xff09;在3GPP系统中的增强支持。文章提出了多个无人机应用场景&#xff0c;分析了相应的能力要求&#xff0c;并建议了新的服务级别要求和关键性能指标&#xff08;KPIs&#xff09;。…

BGP笔记的基本概要

技术背景&#xff1a; 在只有IGP&#xff08;诸如OSPF、IS-IS、RIP等协议&#xff0c;因为最初是被设计在一个单域中进行一个路由操纵&#xff0c;因此被统一称为Interior Gateway Protocol&#xff0c;内部网关协议&#xff09;的时代&#xff0c;域间路由无法实现一个全局路由…

Hadolint提升Dockerfile的质量和安全性 —— 筑梦之路

https://github.com/hadolint/hadolint hadolint 在线版本&#xff1a;https://hadolint.github.io/hadolint/ FROM debian RUN export node_version"0.10" \ && apt-get update && apt-get -y install nodejs"$node_verion" COPY packa…

【JavaEE】AOP实现原理

概述 Spring AOP 是基于动态代理来实现AOP的, 此处主要介绍代理模式和Spring AOP的源码剖析 一.代理模式 代理模式是一种常用的设计模式&#xff0c;它允许为其他对象提供代理&#xff0c;以控制对这个对象的访问。这种结构在不改变原始类的基础上&#xff0c;通过引入代理类…