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%,开启了涨价模式。沉寂一年多的存储芯片迎来了景气周期。 所…...
Cursor实现用excel数据填充word模版的方法
cursor主页:https://www.cursor.com/ 任务目标:把excel格式的数据里的单元格,按照某一个固定模版填充到word中 文章目录 注意事项逐步生成程序1. 确定格式2. 调试程序 注意事项 直接给一个excel文件和最终呈现的word文件的示例,…...
Lombok 的 @Data 注解失效,未生成 getter/setter 方法引发的HTTP 406 错误
HTTP 状态码 406 (Not Acceptable) 和 500 (Internal Server Error) 是两类完全不同的错误,它们的含义、原因和解决方法都有显著区别。以下是详细对比: 1. HTTP 406 (Not Acceptable) 含义: 客户端请求的内容类型与服务器支持的内容类型不匹…...
R语言AI模型部署方案:精准离线运行详解
R语言AI模型部署方案:精准离线运行详解 一、项目概述 本文将构建一个完整的R语言AI部署解决方案,实现鸢尾花分类模型的训练、保存、离线部署和预测功能。核心特点: 100%离线运行能力自包含环境依赖生产级错误处理跨平台兼容性模型版本管理# 文件结构说明 Iris_AI_Deployme…...
MySQL 隔离级别:脏读、幻读及不可重复读的原理与示例
一、MySQL 隔离级别 MySQL 提供了四种隔离级别,用于控制事务之间的并发访问以及数据的可见性,不同隔离级别对脏读、幻读、不可重复读这几种并发数据问题有着不同的处理方式,具体如下: 隔离级别脏读不可重复读幻读性能特点及锁机制读未提交(READ UNCOMMITTED)允许出现允许…...
STM32F4基本定时器使用和原理详解
STM32F4基本定时器使用和原理详解 前言如何确定定时器挂载在哪条时钟线上配置及使用方法参数配置PrescalerCounter ModeCounter Periodauto-reload preloadTrigger Event Selection 中断配置生成的代码及使用方法初始化代码基本定时器触发DCA或者ADC的代码讲解中断代码定时启动…...
[ICLR 2022]How Much Can CLIP Benefit Vision-and-Language Tasks?
论文网址:pdf 英文是纯手打的!论文原文的summarizing and paraphrasing。可能会出现难以避免的拼写错误和语法错误,若有发现欢迎评论指正!文章偏向于笔记,谨慎食用 目录 1. 心得 2. 论文逐段精读 2.1. Abstract 2…...
CocosCreator 之 JavaScript/TypeScript和Java的相互交互
引擎版本: 3.8.1 语言: JavaScript/TypeScript、C、Java 环境:Window 参考:Java原生反射机制 您好,我是鹤九日! 回顾 在上篇文章中:CocosCreator Android项目接入UnityAds 广告SDK。 我们简单讲…...
【碎碎念】宝可梦 Mesh GO : 基于MESH网络的口袋妖怪 宝可梦GO游戏自组网系统
目录 游戏说明《宝可梦 Mesh GO》 —— 局域宝可梦探索Pokmon GO 类游戏核心理念应用场景Mesh 特性 宝可梦玩法融合设计游戏构想要素1. 地图探索(基于物理空间 广播范围)2. 野生宝可梦生成与广播3. 对战系统4. 道具与通信5. 延伸玩法 安全性设计 技术选…...
HashMap中的put方法执行流程(流程图)
1 put操作整体流程 HashMap 的 put 操作是其最核心的功能之一。在 JDK 1.8 及以后版本中,其主要逻辑封装在 putVal 这个内部方法中。整个过程大致如下: 初始判断与哈希计算: 首先,putVal 方法会检查当前的 table(也就…...
Java + Spring Boot + Mybatis 实现批量插入
在 Java 中使用 Spring Boot 和 MyBatis 实现批量插入可以通过以下步骤完成。这里提供两种常用方法:使用 MyBatis 的 <foreach> 标签和批处理模式(ExecutorType.BATCH)。 方法一:使用 XML 的 <foreach> 标签ÿ…...
