当前位置: 首页 > news >正文

SpringBoot 2.x ——使用 mail 实现邮件发送

文章目录

  • 前言
  • 环境、版本等
  • pom依赖引入
  • springboot项目配置文件
    • 获取邮箱授权码
    • 配置properties文件
  • 定义接口信息接收类
  • 编写邮件发送服务类
  • 编写接口
  • swagger测试
    • 1、简单邮件发送
    • 2、html格式发送(支持附件)

前言

最近再看xxl-job的源码,其中在邮件告警通知中使用到了告警信息邮件通知的方式,挺有意思的,特写一篇文章进行简单的配置和使用。

环境、版本等

  • springboot 2.1.4.RELEASE
  • jdk 1.8

pom依赖引入

springboot的版本就已经对mail组件进行了控制,只需要引入对应的依赖即可,无需单独设置版本。(也可以设定指定的版本号)

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

springboot项目配置文件

由于加入了spring-boot-starter-mail依赖组件,此时如果需要使用mail功能,还需要进行下面的几项配置。

获取邮箱授权码

进入QQ邮箱的设置,找到账户
在这里插入图片描述
账户项中下滑至POP3/IMAP/SMTP/Exchange/CardDAV/CalDAV服务
在这里插入图片描述

选择生成授权码。需要发送确认短信信息,当发送成功后,将会获得当前邮箱的授权码信息
将授权码信息复制粘贴到spring.mail.password中即可!

配置properties文件

创建application.properties文件,并在其中配置如下信息:

server.port=80spring.mail.host=smtp.qq.com
spring.mail.port=25
spring.mail.username=302592372@qq.com
spring.mail.from=302592372@qq.com    # 邮件发送者
spring.mail.password=邮箱授权码
spring.mail.properties.mail.smtp.auth=true
spring.mail.properties.mail.smtp.starttls.enable=true
spring.mail.properties.mail.smtp.starttls.required=true
spring.mail.properties.mail.smtp.socketFactory.class=javax.net.ssl.SSLSocketFactory

定义接口信息接收类

主要是接口传递参数使用,如下结构:

import lombok.Data;
import java.io.Serializable;@Data
public class MailRequest implements Serializable {/*** 接收人*/private String sendTo;/*** 邮件主题*/private String subject;/*** 邮件内容*/private String text;/*** 附件路径*/private String filePath;}

编写邮件发送服务类

编写邮件发送操作的服务类,使用两种方式:简单邮件内容发送html邮件内容发送

import cn.xj.emails.uo.MailRequest;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
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.stereotype.Service;
import org.springframework.util.StringUtils;import javax.mail.MessagingException;
import javax.mail.internet.MimeMessage;
import java.io.File;
import java.util.Date;@Slf4j
@Service
public class SendMailService {@Autowiredprivate JavaMailSender javaMailSender;@Value("${spring.mail.from}")private String sendMailer;/*** 简单邮件内容发送* @param mailRequest*/public void sendSimpleMail(MailRequest mailRequest) {SimpleMailMessage message = new SimpleMailMessage();//邮件发件人message.setFrom(sendMailer);//邮件收件人 1或多个message.setTo(mailRequest.getSendTo().split(","));//邮件主题message.setSubject(mailRequest.getSubject());//邮件内容message.setText(mailRequest.getText());//邮件发送时间message.setSentDate(new Date());javaMailSender.send(message);log.info("发送邮件成功:{}->{}",sendMailer,mailRequest.getSendTo());}/*** Html格式邮件,可带附件* @param mailRequest*/public void sendHtmlMail(MailRequest mailRequest) {MimeMessage message = javaMailSender.createMimeMessage();try {MimeMessageHelper helper = new MimeMessageHelper(message,true);//邮件发件人helper.setFrom(sendMailer);//邮件收件人 1或多个helper.setTo(mailRequest.getSendTo().split(","));//邮件主题helper.setSubject(mailRequest.getSubject());//邮件内容helper.setText(mailRequest.getText(),true);//邮件发送时间helper.setSentDate(new Date());String filePath = mailRequest.getFilePath();if (StringUtils.hasText(filePath)) {FileSystemResource file = new FileSystemResource(new File(filePath));String fileName = filePath.substring(filePath.lastIndexOf(File.separator));helper.addAttachment(fileName,file);}javaMailSender.send(message);log.info("发送邮件成功:{}->{}",sendMailer,mailRequest.getSendTo());} catch (MessagingException e) {log.error("发送邮件时发生异常!",e);}}
}

编写接口

制定一个测试 controller,进行简单的接口开发。

import cn.xj.emails.service.SendMailService;
import cn.xj.emails.uo.MailRequest;
import io.swagger.annotations.Api;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;@RestController
@RequestMapping("/email")
@Api(value = "发送邮件接口",tags = {"发送邮件接口"})
public class TestController {@Autowiredprivate SendMailService sendMailService;@PostMapping("/simple")public void SendSimpleMessage(@RequestBody MailRequest mailRequest) {sendMailService.sendSimpleMail(mailRequest);}@PostMapping("/html")public void SendHtmlMessage(@RequestBody MailRequest mailRequest) { sendMailService.sendHtmlMail(mailRequest);}
}

swagger测试

为了测试的方便,项目中整合了swagger2进行接口测试,当然也可以使用postman等工具。

1、简单邮件发送

/email/simple

在这里插入图片描述
收到邮件如下:
在这里插入图片描述

2、html格式发送(支持附件)

/email/html

在这里插入图片描述
收到的邮件如下所示:
在这里插入图片描述

相关文章:

SpringBoot 2.x ——使用 mail 实现邮件发送

文章目录前言环境、版本等pom依赖引入springboot项目配置文件获取邮箱授权码配置properties文件定义接口信息接收类编写邮件发送服务类编写接口swagger测试1、简单邮件发送2、html格式发送(支持附件)前言 最近再看xxl-job的源码&#xff0c;其中在邮件告警通知中使用到了告警信…...

项目结束先别着急庆祝,项目经理还有这些事要做

项目管理生命周期结束阶段的目的是确认项目可交付成果的完成&#xff0c;使项目发起人满意&#xff0c;并向所有参与者和利益相关者传达项目的最终处置和状态。 项目结束确保项目的所有参与者和利益相关者都清楚后续活动&#xff08;如新项目、服务过渡、SLA等&#xff09;&a…...

没想到的 IIFE

没想到的 IIFE 有时候我们想要立即执行一下所定义的函数&#xff0c;可以怎么做呢&#xff1f; function foo(num) {return num ?? 1; }foo();写完然后调用对吧&#xff0c;这是可以的&#xff0c;但你有没有觉得这其实有点脱裤子放屁了&#xff0c;完全可以直接调用就是了…...

「牛客网C」初学者入门训练BC156

&#x1f436;博主主页&#xff1a;ᰔᩚ. 一怀明月ꦿ ❤️‍&#x1f525;专栏系列&#xff1a;线性代数&#xff0c;C初学者入门训练 &#x1f525;座右铭&#xff1a;“不要等到什么都没有了&#xff0c;才下定决心去做” &#x1f680;&#x1f680;&#x1f680;大家觉不错…...

【Proteus仿真】【STM32单片机】粮仓温湿度控制系统设计

文章目录一、功能简介二、软件设计三、实验现象联系作者一、功能简介 本项目使用Proteus8仿真STM32单片机控制器&#xff0c;使用声光报警模块、LCD1602显示模块、DHT11温湿度模块、继电器模块、加热加湿除湿风扇等。 主要功能&#xff1a; 系统运行后&#xff0c;LCD1602显示…...

九年时间,倾情投入,JumpServer开源堡垒机v3.0正式发布

2023年2月27日&#xff0c;JumpServer开源堡垒机正式发布v3.0版本。在JumpServer开源堡垒机v3.0版本的设计过程中&#xff0c;我们始终秉持着“内外兼修”的原则&#xff0c;旨在进一步提升用户的使用体验&#xff0c;真正用心做好一款开源堡垒机。 在JumpServer v3.0版本中&…...

【ROS学习笔记5】服务通信

【ROS学习笔记5】服务通信 文章目录【ROS学习笔记5】服务通信前言一、服务通信的理论模型二、服务通信自定义srv三、服务通信自定义srv的Cpp实现四、服务通信自定义srv的Python实现五、Reference写在前面&#xff0c;本系列笔记参考的是AutoLabor的教程&#xff0c;具体项目地址…...

“华为杯”研究生数学建模竞赛2006年-【华为杯】A题:Ad Hoc 网络中的区域划分和资源分配问题(附获奖论文)

赛题描述 Ad Hoc网络是当前网络和通信技术研究的热点之一,对于诸如军队和在野外作业的大型公司和集团来说,Ad Hoc网络有着无需基站、无需特定交换和路由节点、随机组建、灵活接入、移动方便等特点,因而具有极大的吸引力。 在Ad Hoc网络中,节点之间的通信均通过无线传输来完…...

编写第一个JAVA程序,常见踩坑记录

编写第一个JAVA程序 预备环境 电脑需要安装JDK 及 配置环境变量打开cmd 输入java -version 能运行在说 创建工程 创建文件夹javaCode(随意叫…) 创建文件Hello.java 编写代码 public class Hello{public static void main(String[] args){System.out.print("hello wo…...

求职陷阱:Lazarus组织以日本瑞穗銀行等招聘信息为诱饵的攻击活动分析

概述 Lazarus组织是疑似具有东北亚背景的APT组织&#xff0c;奇安信威胁情报中心内部追踪编号为APT-Q-1&#xff0c;因2014年攻击索尼影业开始受到广泛关注&#xff0c;其攻击活动最早可追溯到2007年。该组织早期主要针对其他国家政府机构&#xff0c;以窃取敏感情报为目的&am…...

【C语言每日一题】判断字符串旋转结果(附加字符串左旋详解)

【C语言每日一题】—— 判断字符串旋转结果&#x1f60e;&#x1f60e;&#x1f60e; 目录 &#x1f4a1;前言&#x1f31e;&#xff1a; &#x1f49b;字符串左旋题目&#x1f49b; &#x1f4aa; 解题思路的分享&#x1f4aa; &#x1f60a;题目源码的分享&#x1…...

SpringSecurity+JWT+Redis进行用户鉴权和接口权限的控制

系统的登录&#xff0c;都做些什么&#xff1f;用户访问登录页时&#xff1a;会发起一个获取图片验证码的请求&#xff0c;后端先生成一个uuid代表此次的验证码,接着生成 "ab?答案" 的表达式&#xff0c;将前面的内容转换成流生成图片&#xff0c;后面的答案则存储到…...

七大排序(Java)

目录 一、插入排序 1. 直接插入排序 2. 希尔排序 二、选择排序 1. 直接选择排序 2. 堆排序 三、交换排序 1. 冒泡排序 2. 快速排序 四、归并排序 五、总结 一、插入排序 1. 直接插入排序 抓一张牌&#xff0c;在有序的牌中&#xff0c;找到合适的位置并且插入。 时间…...

分享一些可以快速掌握python语法的小技巧

下面是我总结的一些有助于快速掌握 Python 语法的小技巧&#xff0c;欢迎一起交流。 注释&#xff1a;在代码中添加注释可以帮助你和其他人理解代码的目的和功能。在 Python 中&#xff0c;使用 # 符号来添加单行注释&#xff0c;使用三引号 """ 或 来添加多行…...

1.FFmpeg-音视频基础

专栏介绍基于最新的FFmpeg5.1.2版本讲解学习, 跟随博主一起学习ffmpeg: 本专栏学习流程为: FFmpeg安装、...

Parasoft的自动化测试平台到底强在哪?

在如今产品迭代如此之快的大背景下&#xff0c;软件测试这项工作越来越被大家所重视&#xff0c;但是通常情况下大家都是选择在产品上线前再去做测试&#xff0c;这个时候就会面临很多麻烦和挑战。首先&#xff0c;产品已经开发好之后&#xff0c;体量比较大&#xff0c;要从哪…...

FastDDS-0.简介

FastDDS简介 eProsima Fast DDS 是 DDS (Data Distribution Service) 协议的一个C语言实现版本&#xff0c;该协议由 Object Management Group (OMG) 组织定义。 eProsima Fast DDS 库既提供了一个应用编程接口&#xff08;API&#xff09;&#xff0c;又提供了一种通信协议&a…...

Flutter入门进阶之旅 -开源Flutter项目

开源Flutter项目 该项目为纯flutter端项目&#xff0c;采用aar方式寄生在原生APP中&#xff0c;作为APP中的一个独立模块 在业务逻辑上做到与原生APP完全隔离&#xff0c;Flutter端开发者&#xff0c;可完全不用关注原生端的业务模块 两端开发彼此业务隔离&#xff0c;缩小了对…...

Opencv项目实战:21 美国ASL手势识别

0、项目介绍 首先&#xff0c;我可以保证在这里&#xff0c;你并不需要多么了解深的机器学习算法&#xff0c;我的初衷是通过本项目&#xff0c;激发大家学习机器学习的动力。选择这种手势原因是因为只有24个字母&#xff0c;你的电脑足以带的动&#xff0c;虽然我只训练A、B、…...

强化学习RL 01: Reinforcement Learning 基础

目录 RL理解要点 1. RL数学基础 1.1 Random Variable 随机变量 1.2 概率密度函数 Probability Density Function(PDF) 1.3 期望 Expectation 1.4 随机抽样 Random Sampling 2. RL术语 Terminologies 2.1 agent、state 和 action 2.2 策略 policy π 2.3 奖励 reward …...

后进先出(LIFO)详解

LIFO 是 Last In, First Out 的缩写&#xff0c;中文译为后进先出。这是一种数据结构的工作原则&#xff0c;类似于一摞盘子或一叠书本&#xff1a; 最后放进去的元素最先出来 -想象往筒状容器里放盘子&#xff1a; &#xff08;1&#xff09;你放进的最后一个盘子&#xff08…...

Linux应用开发之网络套接字编程(实例篇)

服务端与客户端单连接 服务端代码 #include <sys/socket.h> #include <sys/types.h> #include <netinet/in.h> #include <stdio.h> #include <stdlib.h> #include <string.h> #include <arpa/inet.h> #include <pthread.h> …...

挑战杯推荐项目

“人工智能”创意赛 - 智能艺术创作助手&#xff1a;借助大模型技术&#xff0c;开发能根据用户输入的主题、风格等要求&#xff0c;生成绘画、音乐、文学作品等多种形式艺术创作灵感或初稿的应用&#xff0c;帮助艺术家和创意爱好者激发创意、提高创作效率。 ​ - 个性化梦境…...

19c补丁后oracle属主变化,导致不能识别磁盘组

补丁后服务器重启&#xff0c;数据库再次无法启动 ORA01017: invalid username/password; logon denied Oracle 19c 在打上 19.23 或以上补丁版本后&#xff0c;存在与用户组权限相关的问题。具体表现为&#xff0c;Oracle 实例的运行用户&#xff08;oracle&#xff09;和集…...

深入理解JavaScript设计模式之单例模式

目录 什么是单例模式为什么需要单例模式常见应用场景包括 单例模式实现透明单例模式实现不透明单例模式用代理实现单例模式javaScript中的单例模式使用命名空间使用闭包封装私有变量 惰性单例通用的惰性单例 结语 什么是单例模式 单例模式&#xff08;Singleton Pattern&#…...

全球首个30米分辨率湿地数据集(2000—2022)

数据简介 今天我们分享的数据是全球30米分辨率湿地数据集&#xff0c;包含8种湿地亚类&#xff0c;该数据以0.5X0.5的瓦片存储&#xff0c;我们整理了所有属于中国的瓦片名称与其对应省份&#xff0c;方便大家研究使用。 该数据集作为全球首个30米分辨率、覆盖2000–2022年时间…...

NPOI操作EXCEL文件 ——CAD C# 二次开发

缺点:dll.版本容易加载错误。CAD加载插件时&#xff0c;没有加载所有类库。插件运行过程中用到某个类库&#xff0c;会从CAD的安装目录找&#xff0c;找不到就报错了。 【方案2】让CAD在加载过程中把类库加载到内存 【方案3】是发现缺少了哪个库&#xff0c;就用插件程序加载进…...

PostgreSQL——环境搭建

一、Linux # 安装 PostgreSQL 15 仓库 sudo dnf install -y https://download.postgresql.org/pub/repos/yum/reporpms/EL-$(rpm -E %{rhel})-x86_64/pgdg-redhat-repo-latest.noarch.rpm# 安装之前先确认是否已经存在PostgreSQL rpm -qa | grep postgres# 如果存在&#xff0…...

从物理机到云原生:全面解析计算虚拟化技术的演进与应用

前言&#xff1a;我的虚拟化技术探索之旅 我最早接触"虚拟机"的概念是从Java开始的——JVM&#xff08;Java Virtual Machine&#xff09;让"一次编写&#xff0c;到处运行"成为可能。这个软件层面的虚拟化让我着迷&#xff0c;但直到后来接触VMware和Doc…...

C# winform教程(二)----checkbox

一、作用 提供一个用户选择或者不选的状态&#xff0c;这是一个可以多选的控件。 二、属性 其实功能大差不差&#xff0c;除了特殊的几个外&#xff0c;与button基本相同&#xff0c;所有说几个独有的 checkbox属性 名称内容含义appearance控件外观可以变成按钮形状checkali…...