SpringBoot发送Gmail邮件
1. 登录Gmail
Gmail网址
点击右上角“小齿轮”,然后点击"查看所有设置"

点击“转发和 POP/IMAP”,按图中设置,然后点击保存:

2. 启用两步验证(https://myaccount.google.com/security)
登录上述网址,找到“安全”(Security)
点击“两步验证”

开启“两步验证”,小编这里已经开启了,所以显示的关闭.

3. 创建应用程序密码
搜索"App passwords",点击第一个
输入程序名称,点击“创建”后会显示一个密码,该密码可以用来发送邮件.

4. Java程序实现(方式1)
4.1 导入依赖
<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-mail</artifactId>
</dependency>
4.2 yml配置
springmail:host: smtp.gmail.comport: 587username: xxx@gmail.compassword: xxx # 第三步的应用程序密码properties:mail:smtp:auth: truestarttls:enable: truerequired: true
4.3 代码
import jakarta.mail.MessagingException;
import jakarta.mail.internet.MimeMessage;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.mail.SimpleMailMessage;
import org.springframework.mail.javamail.JavaMailSender;
import org.springframework.mail.javamail.MimeMessageHelper;
import org.springframework.stereotype.Service;/*** 邮件发送服务实现类*/
@Slf4j
@RequiredArgsConstructor
@Service
public class MailSendService {@Value("${spring.mail.username}")private String mailFrom;private final JavaMailSender javaMailSender;@Overridepublic void sendMailSimple(String to, String subject, String text) {SimpleMailMessage simpleMailMessage = new SimpleMailMessage();// 发件人simpleMailMessage.setFrom(mailFrom);// 收件人simpleMailMessage.setTo(to);// 邮件主题simpleMailMessage.setSubject(subject);// 邮件内容simpleMailMessage.setText(text);javaMailSender.send(simpleMailMessage);}@Overridepublic void sendWithAttach(String to, String subject, String text, MailAttachInfoDTO ...attachInfos) {MimeMessage message = javaMailSender.createMimeMessage();try{MimeMessageHelper helper = new MimeMessageHelper(message, true);helper.setFrom(mailFrom);helper.setTo(to);helper.setSubject(subject);helper.setText(text);for(MailAttachInfoDTO attachInfo : attachInfos) {if(attachInfo == null) continue;helper.addAttachment(attachInfo.getAttachName(), attachInfo.getAttachSource());}}catch (MessagingException e) {log.warn("MailSendServiceImpl.sendWithAttach failed.", e);}javaMailSender.send(message);}
}
4.4 设置代理
在调试的时候需要梯子,否则可能访问不了Gmail的服务器:
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.data.jpa.repository.config.EnableJpaAuditing;
import org.springframework.scheduling.annotation.EnableScheduling;@EnableScheduling
@EnableJpaAuditing
@SpringBootApplication
public class TestApplication {public static void main(String[] args) {// 设置代理地址、端口 你们调试的时候替换成自己的代理地址端口System.setProperty("http.proxyHost", "192.168.0.12");System.setProperty("http.proxyPort", "10183");SpringApplication.run(TestApplication.class, args);}}
5. Java程序实现(方式2-动态发送者)
由于我们项目中,原本已经存在发送邮件的功能,yml已经配置了其他的邮箱,而此时又来一个新需求,需要使用不同的邮箱来发送。所以这里我使用了动态设置发送人的方式。
DynamicMailSender.java
import org.springframework.mail.javamail.JavaMailSender;
import org.springframework.mail.javamail.JavaMailSenderImpl;import java.util.Properties;public class DynamicMailSender {public static JavaMailSender createGmailSender(String username, String password) {JavaMailSenderImpl mailSender = new JavaMailSenderImpl();mailSender.setHost("smtp.gmail.com");mailSender.setPort(587);mailSender.setUsername(username);mailSender.setPassword(password);Properties props = mailSender.getJavaMailProperties();props.put("mail.transport.protocol", "smtp");props.put("mail.smtp.auth", "true");props.put("mail.smtp.starttls.enable", "true");
// props.put("mail.smtp.connectiontimeout", "5000");
// props.put("mail.smtp.timeout", "5000");
// props.put("mail.smtp.writetimeout", "5000");props.put("mail.debug", "true");return mailSender;}
}
EmailService.java
import jakarta.mail.internet.MimeMessage;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.mail.SimpleMailMessage;
import org.springframework.mail.javamail.JavaMailSender;
import org.springframework.mail.javamail.MimeMessageHelper;
import org.springframework.stereotype.Service;@Slf4j
@Service
public class EmailService {/*** 发送Gmail邮件* @param from 发送者邮箱* @param password 应用程序密码* @param to 接收者邮箱* @param subject 邮件主题* @param text 邮件内容* @return 发送是否成功*/public boolean sendGmailSimple(String from, String password, String to, String subject, String text) {try {JavaMailSender mailSender = DynamicMailSender.createGmailSender(from, password);SimpleMailMessage message = new SimpleMailMessage();message.setFrom(from);message.setTo(to);message.setSubject(subject);message.setText(text);mailSender.send(message);return true;} catch (Exception e) {log.info("EmailService 发送gmail失败.", e);}return false;}/*** 发送Gmail邮件* @param fromEmail 发送者邮箱* @param fromName 发送者昵称* @param password 应用程序密码* @param to 接收者邮箱* @param subject 邮件主题* @param text 邮件内容* @return 发送是否成功*/public boolean sendGmailSimple(String fromEmail, String fromName, String password, String to, String subject, String text) {if (StringUtils.isBlank(fromName)) {return sendGmailSimple(fromEmail, password, to, subject, text);}return sendGmailSimple(fromEmail, fromName, password, to, subject, text, false);}/*** 发送Gmail邮件* @param fromEmail 发送者邮箱* @param fromName 发送者昵称* @param password 应用程序密码* @param to 接收者邮箱* @param subject 邮件主题* @param text 邮件内容* @param html 内容是否使用html格式* @return 发送是否成功*/public boolean sendGmailSimple(String fromEmail, String fromName, String password, String to, String subject, String text, boolean html) {try {JavaMailSender mailSender = DynamicMailSender.createGmailSender(fromEmail, password);MimeMessage message = mailSender.createMimeMessage();MimeMessageHelper helper = new MimeMessageHelper(message, true);helper.setFrom(fromEmail, fromName);helper.setTo(to);helper.setSubject(subject);helper.setText(text, html);mailSender.send(message);return true;} catch (Exception e) {log.info("EmailService 发送gmail失败.", e);}return false;}
}相关文章:
SpringBoot发送Gmail邮件
1. 登录Gmail Gmail网址 点击右上角“小齿轮”,然后点击"查看所有设置" 点击“转发和 POP/IMAP”,按图中设置,然后点击保存: 2. 启用两步验证(https://myaccount.google.com/security) 登录上述网址,找…...
【小海实习日记】金融-现货以及合约理解
在股票和金融市场中,“单项持仓”和“双向持仓”是两个常见的概念,主要用于描述投资者在市场中的头寸及其策略。 单项持仓(单向持仓) 单项持仓是指投资者在市场中只持有一种方向的头寸(多头或空头)&#…...
html 添加元素如何能提升速度
在 HTML 中,如果你需要频繁地添加大量元素,需要确保你的操作能够以最佳性能进行。以下是一些有助于提高添加元素速度的方法: 综上所述,通过使用文档片段、innerHTML、虚拟滚动以及避免频繁的重排和重绘,你可以提高在 H…...
人工智能大模型的进化之路:探索如何让它们变得更“聪明”
一、引言 在人工智能(AI)领域,大模型凭借其强大的处理能力和广泛的应用前景,已经成为研究的热点。然而,尽管这些模型在多个领域展现出了惊人的能力,但它们仍然面临着理解力、泛化能力和适应性等方面的挑战…...
【设计模式深度剖析】【6】【结构型】【外观模式】| 以电脑开关按钮为例,并结合微服务架构的API网关加深理解
👈️上一篇:桥接模式 | 下一篇:享元模式👉️ 设计模式-专栏👈️ 目 录 外观模式(Facade Pattern)定义英文原文直译如何理解呢?字面理解代码实现中的理解生活案例:操作多功能料理机典型案例…...
2024拼多多 最新理论+实战干货,从入门到精通全链路多角度学习-7节课
基于最新规则理论结合实际的干货 课程内容: 01 2024年多多防比价新规则破局理论课与实操课.mp4 02 24年多多强付费第二节课基础内功.mp4 03 24年多多强付费第三节课直通车实操 .mp4 04 24年多多强付费第一节课市场定价格段,mp4 05 24年多多自然流第一节课市场…...
在Three.js中实现模型点击高亮:整合EffectComposer与OutlinePass的终极指南
效果【后期实现鼠标点击选中轮廓后给出一个弹窗显示相应的模型信息】 标签指示线参考我的上一篇文章 引言 Three.js不仅让WebGL的3D图形编程变得简单易懂,还通过其强大的扩展库支持丰富的后期处理效果,为3D场景增添无限魅力。本篇文章将引导您深入了…...
Webrtc支持HEVC之FFMPEG支持HEVC编解码(一)
一、前言 Webrtc使用的FFMPEG(webrtc\src\third_party\ffmpeg)和官方的不太一样,使用GN编译,各个平台使用了不一样的配置文件 以Windows为例,Chrome浏览器也类似 二、修改配置文件 windows:chromium\config\Chrome\win\x64 其他平台: chromium\config\Chrome\YOUR_SYS…...
高校实验室危险化学品及重大危险源安全管理系统
高校实验室危险化学品及重大危险源安全管理的重要性: 保障师生安全:通过严格管理,可以有效地降低这些风险,确保师生在实验室内的安全。 确保实验教学质量:良好的危化品管理能够确保实验材料的准确性和可靠性࿰…...
【Godot4自学手册】第四十一节背包系统(一)UI设置
各位同学,好久没有更新笔记了,今天开始,我准备自学背包系统。今天先学习下UI界面设置。 一、新建场景和结点 1.新建Node2D场景,命名为Inventory,保存到Scenes目录下,inventory.tscn。 2.新建TextureRect子…...
JS继承的方式
目录 原型链继承构造函数继承组合继承寄生组合继承ES6 Class 继承原型链继承 原理: 通过将子类的原型(prototype)设置为父类的一个实例,使得子类实例能够沿着原型链访问到父类的属性和方法。 function Parent() {this.parentProperty...
拓展虚拟世界边界,云手机可以做到吗
虚拟世界,AI,VR等词汇是21世纪最为流行的词汇,在科技背后,这些词汇的影响变得越来越大,已经走进了人们的世界,比如之前APPLE发布的vision pro,使人们能够更加身临其境的体验到原生os系统&#x…...
网络的功能和实现方法简介
网络的功能: 计算机网络是研究怎么样在两个端用户之间提供访问通路的。所以网络的功能是为网络上的任意两个端用户之间提供访问通路。 计算机通信的特点: 间歇性和突发性。即时而线路中没有信息流过,时而突来的大量数据需要迅速传输。为此计…...
npm有哪些插件包??
1.Web开发相关 Web开发相关的npm插件包涵盖了各种工具、框架和库,帮助开发人员简化开发流程、提高效率并实现更好的用户体验。以下是一些常见的Web开发相关的npm插件包及其功能: 1. webpack:一个现代的JavaScript应用程序的静态模块打包工具…...
SpringBoot基础篇
1:parent 目的:减少依赖配置 开发SpringBoot程序要继承spring-boot-starter-parentspring-boot-starter-parent中定义了若干个依赖管理继承parent模块可以避免多个依赖使用相同技术出现依赖版本冲突继承parent的形式也可以采用引入依赖的i形式实现效果…...
【java11】java11新特性介绍
Java11于2018年9月25日正式发布,Java11是继Java8之后的第一个LTS(Long-Term-Support)长期支持功能版本,与之前的版本(Java9和Java10)不同,它提供了长达3年的维护期,旨在提供稳定且长…...
搜维尔科技:介绍下Manus的OptiTrack 手套,体验精致的每指触觉!
搜维尔科技:介绍下Manus的OptiTrack 手套,体验精致的每指触觉! 搜维尔科技:介绍下Manus的OptiTrack 手套,体验精致的每指触觉!...
Element ui 快速入门(基础知识点)
element ui官网 前言: 在当今时代,我们在编写计算机程序时,不仅仅是写几个增删改查的简单功能,为了满足广大用户对页面美观的需求,为了让程序员们写一些功能更简便,提高团队协作效率,所以eleme…...
[数据集][目标检测]脑肿瘤检测数据集VOC+YOLO格式9787张3类别
数据集格式:Pascal VOC格式YOLO格式(不包含分割路径的txt文件,仅仅包含jpg图片以及对应的VOC格式xml文件和yolo格式txt文件) 图片数量(jpg文件个数):9787 标注数量(xml文件个数):9787 标注数量(txt文件个数):9787 标注…...
兆易创新:周期已至 触底反弹?
韩国那边来的数据啊,4月芯片库存同比下降33.7%,创近10年以来(最)大降幅,芯片出口同比增长53.9%,其中存储芯片出口额同比大幅增长98.7%,开启了涨价模式。沉寂一年多的存储芯片迎来了景气周期。 所…...
装饰模式(Decorator Pattern)重构java邮件发奖系统实战
前言 现在我们有个如下的需求,设计一个邮件发奖的小系统, 需求 1.数据验证 → 2. 敏感信息加密 → 3. 日志记录 → 4. 实际发送邮件 装饰器模式(Decorator Pattern)允许向一个现有的对象添加新的功能,同时又不改变其…...
深入浅出:JavaScript 中的 `window.crypto.getRandomValues()` 方法
深入浅出:JavaScript 中的 window.crypto.getRandomValues() 方法 在现代 Web 开发中,随机数的生成看似简单,却隐藏着许多玄机。无论是生成密码、加密密钥,还是创建安全令牌,随机数的质量直接关系到系统的安全性。Jav…...
Linux相关概念和易错知识点(42)(TCP的连接管理、可靠性、面临复杂网络的处理)
目录 1.TCP的连接管理机制(1)三次握手①握手过程②对握手过程的理解 (2)四次挥手(3)握手和挥手的触发(4)状态切换①挥手过程中状态的切换②握手过程中状态的切换 2.TCP的可靠性&…...
为什么需要建设工程项目管理?工程项目管理有哪些亮点功能?
在建筑行业,项目管理的重要性不言而喻。随着工程规模的扩大、技术复杂度的提升,传统的管理模式已经难以满足现代工程的需求。过去,许多企业依赖手工记录、口头沟通和分散的信息管理,导致效率低下、成本失控、风险频发。例如&#…...
(二)原型模式
原型的功能是将一个已经存在的对象作为源目标,其余对象都是通过这个源目标创建。发挥复制的作用就是原型模式的核心思想。 一、源型模式的定义 原型模式是指第二次创建对象可以通过复制已经存在的原型对象来实现,忽略对象创建过程中的其它细节。 📌 核心特点: 避免重复初…...
【SQL学习笔记1】增删改查+多表连接全解析(内附SQL免费在线练习工具)
可以使用Sqliteviz这个网站免费编写sql语句,它能够让用户直接在浏览器内练习SQL的语法,不需要安装任何软件。 链接如下: sqliteviz 注意: 在转写SQL语法时,关键字之间有一个特定的顺序,这个顺序会影响到…...
鸿蒙中用HarmonyOS SDK应用服务 HarmonyOS5开发一个医院查看报告小程序
一、开发环境准备 工具安装: 下载安装DevEco Studio 4.0(支持HarmonyOS 5)配置HarmonyOS SDK 5.0确保Node.js版本≥14 项目初始化: ohpm init harmony/hospital-report-app 二、核心功能模块实现 1. 报告列表…...
sqlserver 根据指定字符 解析拼接字符串
DECLARE LotNo NVARCHAR(50)A,B,C DECLARE xml XML ( SELECT <x> REPLACE(LotNo, ,, </x><x>) </x> ) DECLARE ErrorCode NVARCHAR(50) -- 提取 XML 中的值 SELECT value x.value(., VARCHAR(MAX))…...
AI病理诊断七剑下天山,医疗未来触手可及
一、病理诊断困局:刀尖上的医学艺术 1.1 金标准背后的隐痛 病理诊断被誉为"诊断的诊断",医生需通过显微镜观察组织切片,在细胞迷宫中捕捉癌变信号。某省病理质控报告显示,基层医院误诊率达12%-15%,专家会诊…...
4. TypeScript 类型推断与类型组合
一、类型推断 (一) 什么是类型推断 TypeScript 的类型推断会根据变量、函数返回值、对象和数组的赋值和使用方式,自动确定它们的类型。 这一特性减少了显式类型注解的需要,在保持类型安全的同时简化了代码。通过分析上下文和初始值,TypeSc…...
