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

使用SMTP javamail发送邮件

一、SMTP协议

        SMTP(Simple Mail Transfer Protocol)即简单邮件传输协议,它是一组用于由源地址到目的地址传送邮件的规则,由它来控制信件的中转方式。SMTP协议属于TCP/IP协议簇,它帮助每台计算机在发送或中转信件时找到下一个目的地。使用javamail编写发送程序发送邮件。

以QQ邮箱为例:

需要开启SMTP服务,设置授权码。授权码不是登录密码,授权码是QQ邮箱用于登录第三方客户端/服务的专用密码,适用于登录以下服务:POP3/IMAP/SMTP/Exchange/CardDAV/CalDAV 服务。不同邮箱可能不一样。

还需要服务器地址,QQ 邮箱的服务器地址 (host) 是:

收信服务器 (POP3) : pop.qq.com

发信服务器 (SMTP) : smtp.qq.com

 二、代码编写

 1、配置文件

可以将邮件的账号密码等放入配置文件

#邮件配置,需要修改密码。username:账号,password:密码/授权码,serverUrl:服务器地址,serverPort:服务器端口,sendMail:邮箱
email:username: 1074004100@qq.compassword:serverUrl: smtp.qq.comserverPort: 25sendMail: 1074004100@qq.com

配置对象:

package com.example.demo.config;import lombok.Data;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Configuration;
import org.springframework.stereotype.Component;/*** @author zhanglei* @date : 2023/03/06 14:14* 邮箱配置*/
@Component
@Configuration
@Data
public class EmailConfig {/*** 邮件账号*/@Value("${email.username}")private String username;/*** 邮件密码/授权码*/@Value("${email.password}")private String password;/*** 服务器地址*/@Value("${email.serverUrl}")private String serverUrl;/*** 服务器端口*/@Value("${email.serverPort}")private Integer serverPort;/*** 发送邮箱*/@Value("${email.sendMail}")private String sendMail;}

2、发送方法

参数对象:

package com.example.demo.entity;import lombok.Data;import java.util.List;/*** 邮件内容* @author zhanglei*/
@Data
public class MailContent {/*** 邮件标题*/private String subject;/*** 邮件内容*/private String text;/*** 附件名称*/private List<String> attachmentNameList;/*** 附件地址*/private List<String> attachmentUrlList;/*** 目标邮箱*/private String toEmail;/*** 抄送邮箱*/private String ccEmail;}

发送方法:

package com.example.demo.util;import com.example.demo.config.EmailConfig;
import com.example.demo.entity.MailContent;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.io.ByteArrayResource;
import org.springframework.mail.javamail.JavaMailSenderImpl;
import org.springframework.mail.javamail.MimeMessageHelper;
import org.springframework.stereotype.Component;import javax.mail.PasswordAuthentication;
import javax.mail.Session;
import javax.mail.internet.MimeMessage;
import javax.mail.internet.MimeUtility;
import java.util.ArrayList;
import java.util.List;
import java.util.Properties;/*** 自定义邮箱发送邮件** @author zhanglei* @version 1.0* @date 2024-03-05 15:08*/
@Component
public class MailSendSmtp {/*** 默认端口号*/public static final Integer MAIL_DEFAULT_PORT = 25;@Autowiredprivate EmailConfig emailConfig;/*{"attachmentNameList": ["附件名.pdf"],"attachmentUrlList": ["https://invtest.nntest.cn/fp/BoRzE95ScXVqSZDehEhBZbz0YyYUFDwZ4Rr8oEuLzBfeM7rFoDSjYRKObeRPOHXyAnrfgbHtf4mz5r3-qvJRvQ.pdf"],"ccEmail": "","subject": "测试邮件","text": "你好,这个测试邮件,请忽略","toEmail": "1953623531.qq.com"}*//*** 发送邮件,自己发送,不使用消息中心** @param mailContent 邮件内容* @throws Exception 异常*/public boolean send(MailContent mailContent) {try {//抄送地址List<String> addresses = new ArrayList<>();addresses.add(mailContent.getToEmail());if (StringUtils.isNotBlank(mailContent.getCcEmail())) {String[] ccs = mailContent.getCcEmail().split(";");for (String addr : ccs) {if (StringUtils.isNotBlank(addr)) {addresses.add(addr);}}}JavaMailSenderImpl javaMailSender = new JavaMailSenderImpl();// 设置邮件内容格式javaMailSender.setDefaultEncoding("utf-8");MimeMessage mimeMessage = javaMailSender.createMimeMessage();MimeMessageHelper helper = new MimeMessageHelper(mimeMessage, true);javaMailSender.setHost(emailConfig.getServerUrl());// 设置默认端口,防止使用域名的时候,解析不正确Integer port = emailConfig.getServerPort() == null ? MAIL_DEFAULT_PORT : emailConfig.getServerPort();if (!MAIL_DEFAULT_PORT.equals(port)) {javaMailSender.setPort(port);}javaMailSender.setUsername(emailConfig.getUsername());javaMailSender.setPassword(emailConfig.getPassword());// 如果配置的发送邮箱为空,则使用邮件账号;否则使用发送邮箱helper.setFrom(StringUtils.isBlank(emailConfig.getSendMail()) ? emailConfig.getUsername() : emailConfig.getSendMail());//目标邮箱helper.setTo(mailContent.getToEmail());//邮件内容helper.setText(mailContent.getText(), true);//邮件标题helper.setSubject(mailContent.getSubject());// 增加抄送人if (StringUtils.isNotBlank(mailContent.getCcEmail())) {helper.setCc(addresses.toArray(new String[0]));}//附件,可以是多个,获取文件流if (CollectionUtils.isNotEmpty(mailContent.getAttachmentNameList())) {for (int i = 0; i < mailContent.getAttachmentNameList().size(); i++) {String fileName = mailContent.getAttachmentNameList().get(i);String url = mailContent.getAttachmentUrlList().get(i);byte[] pdfBytes = HttpClientUtil.getRemoteResource(url, 5000);if (pdfBytes != null) {ByteArrayResource pdfResource = new ByteArrayResource(pdfBytes);helper.addAttachment(MimeUtility.encodeText(fileName), pdfResource, "application/pdf");}}}Properties props = new Properties();/*// 增加ssl配置if (mailInfoUtil.isEnableSsl()) {props.put("mail.smtp.auth", "true");props.put("mail.smtp.ssl.enable", "true");}// 增加tsl配置if (mailInfoUtil.isEnableTls()) {props.put("mail.smtp.starttls.enable", "true");props.put("mail.smtp.starttls.required", "true");}*/if (!props.isEmpty()) {Session session = Session.getInstance(props, new javax.mail.Authenticator() {@Overrideprotected javax.mail.PasswordAuthentication getPasswordAuthentication() {return new PasswordAuthentication(emailConfig.getUsername(), emailConfig.getPassword());}});javaMailSender.setSession(session);}// 发送邮件javaMailSender.send(mimeMessage);return true;} catch (Exception e) {return false;}}
}

项目地址:https://gitee.com/itzhl/dynamic-data-source-demo.git

相关文章:

使用SMTP javamail发送邮件

一、SMTP协议 SMTP(Simple Mail Transfer Protocol)即简单邮件传输协议,它是一组用于由源地址到目的地址传送邮件的规则&#xff0c;由它来控制信件的中转方式。SMTP协议属于TCP/IP协议簇&#xff0c;它帮助每台计算机在发送或中转信件时找到下一个目的地。使用javamail编写发送…...

Hello C++ (c++是什么/c++怎么学/c++推荐书籍)

引言 其实C基础语法基本上已经学完&#xff0c;早就想开始写C的博客了&#xff0c;却因为其他各种事情一直没开始。原计划是想讲Linux系统虚拟机安装的&#xff0c;后来考虑了一下还是算了&#xff0c;等Linux学到一定程度再开始相关博客的写作和发表吧。今天写博客想给C开个头…...

最新的前端开发技术(2024年)

关于作者&#xff1a; 还是大剑师兰特&#xff1a;曾是美国某知名大学计算机专业研究生&#xff0c;现为航空航海领域高级前端工程师&#xff1b;CSDN知名博主&#xff0c;GIS领域优质创作者&#xff0c;深耕openlayers、leaflet、mapbox、cesium&#xff0c;canvas&#xff0…...

GCN 翻译 - 2

2 FAST APROXIMATE CONVOLUTIONS ON GRAPHS 在这一章节&#xff0c;我们为这种特殊的的图基础的神经网络模型f(X, A)提供理论上的支持。我们考虑一个多层的图卷积网络&#xff08;GCN&#xff09;&#xff0c;它通过以下方式进行层间的传播&#xff1a; 这里&#xff0c;是无…...

HBase 的安装与部署

目录 1 启动 zookeeper2 启动 Hadoop3 HBase 的安装与部署4 HBase 高可用 1 启动 zookeeper [huweihadoop101 ~]$ bin/zk_cluster.sh start2 启动 Hadoop [huweihadoop101 ~]$ bin/hdp_cluster.sh start3 HBase 的安装与部署 &#xff08;1&#xff09;将 hbase-2.0.5-bin.tar.…...

236.二叉搜索树的公共祖先

236.二叉树的公共祖先 思路 看到题想的是找到两个点的各自路径利用stack保存&#xff0c;根据路径长度大小将两个stack的值对齐到同一层&#xff0c;之后同时出栈节点&#xff0c;若相同则找到祖先节点。但是效率不高 看了大佬代码&#xff0c;递归思想很难理解。 根据大佬…...

【论文精读】大语言模型融合知识图谱的问答系统研究

&#x1f497;&#x1f497;&#x1f497;欢迎来到我的博客&#xff0c;你将找到有关如何使用技术解决问题的文章&#xff0c;也会找到某个技术的学习路线。无论你是何种职业&#xff0c;我都希望我的博客对你有所帮助。最后不要忘记订阅我的博客以获取最新文章&#xff0c;也欢…...

LabVIEW高精度天线自动测试系统

LabVIEW高精度天线自动测试系统 系统是一个集成了LabVIEW软件的自动化天线测试平台&#xff0c;提高天线性能测试的精度与效率。系统通过远程控制测试仪表&#xff0c;实现了数据采集、方向图绘制、参数计算等功能&#xff0c;特别适用于对天线辐射特性的精确测量。 在天线的…...

7.3 支付模块 - 创建订单、查询订单、通知

支付模块 - 创建订单、查询订单、通知 文章目录 支付模块 - 创建订单、查询订单、通知一、生成支付二维码1.1 数据模型1.1.1 订单表1.1.2 订单明细表1.1.3 支付交易记录表 1.2 执行流程1.3 Dto1.3.1 AddOrderDto 商品订单1.3.2 PayRecordDto支付交易记录扩展字段1.3.3 雪花算法…...

灵魂指针,教给(一)

欢迎来到白刘的领域 Miracle_86.-CSDN博客 系列专栏 C语言知识 先赞后看&#xff0c;已成习惯 创作不易&#xff0c;多多支持&#xff01; 一、内存和地址 1.1 内存 在介绍知识之前&#xff0c;先来想一个生活中的小栗子&#xff1a; 假如把你放在一个有100间屋子的酒店…...

Linux 开发工具 yum、git、gdb

目录 一、yum 1、软件包 2、rzsz 3、注意事项 4、查看软件包 5、安装软件 6、卸载软件 二、git操作 1、克隆三板斧 2、第一次使用会出现以下情况&#xff1a; 未配置用户名和邮箱&#xff1a; push后弹出提示 三、gdb使用 1、背景 2、使用方法 例一&#xff1a…...

Markdown

这里写自定义目录标题 欢迎使用Markdown编辑器 新的改变 功能快捷键 合理的创建标题&#xff0c;有助于目录的生成 如何改变文本的样式 插入链接与图片 如何插入一段漂亮的代码片 生成一个适合你的列表 创建一个表格 设定内容居中、居左、居右 SmartyPants 创建一个自定义列表 …...

【Oracle】oracle中sql给表新增字段并添加注释说明;mysql新增、修改字段

oracle中sql给表新增字段并添加注释说明 ALTER TABLE 表名 ADD 字段名 类型 COMMENT ON COLUMN 表面.字段名 IS ‘注释内容’ ALTER TABLE GROUP ADD T NUMBER(18) COMMENT ON COLUMN GROUP.T IS ‘ID’ mysql新增、修改字段、已有字段增加默认值 ALTER TABLE 表名 ADD COL…...

【汇总】pytest简易教程

pytest作为python技术栈里面主流、火热的技术&#xff0c;非常有必要好好学一下&#xff0c;因为工作和面试都能用上&#xff1b; 它不仅简单易用&#xff0c;还很强大灵活&#xff0c;重点掌握fixture、parametrize参数化、allure-pytest插件等&#xff0c;这些在后续自动化框…...

openssl调试记录

openssl不能直接解密16进制密文&#xff0c;需要把密文转化成base64格式才能解密 调试记录如下&#xff1a;...

3.7练习题解

一共五道题&#xff1a; 1. PERKET&#xff1a; 观察容易发现n的值很小&#xff0c;所以我们可以考虑使用dfs的方法进行解答&#xff0c;首先我们可以考虑一共有n种配料&#xff0c;那么我们就可以考虑到可以选择1到n种配料数目&#xff0c;然后基于这个思路我们再对其进行判断…...

MQ的消费模式-消息是推还是拉

文章目录 概述RocketMQ默认pushRabbitMQ默认pushKafka默认拉PullActiveMQ默认push 概述 MQ的消费模式可以大致分为两种&#xff0c;一种是推Push&#xff0c;一种是拉Pull Push是服务端主动推送消息给客户端&#xff0c;Pull是客户端需要主动到服务端轮询获取数据。 推优点是及…...

一个平台满足你对测试工具的所有需求

背景 目前&#xff0c;测试人员普遍使用的测试工具有Postman、JMeter等&#xff0c;但这些工具都存在一定的局限性。例如&#xff0c;Postman缺少对API性能测试方面的支持&#xff0c;而JMeter则缺乏一个整合测试报告、测试脚本的统一管理系统以及UI测试功能。 RunnerGo是什么…...

【C语言】【字符串函数】【超详解】【上】!!!

前言&#xff1a; 在学习C语言的过程中&#xff0c;字符串、字符数组等对新手来说总是会有疏忽&#xff0c;在已有的库函数中&#xff0c;我们平时用到最多的就是关于字符串的函数&#xff0c;今天我们就来详细学习字符串函数的相关内容。 下面我们就开始讲解字符串函数&#x…...

算法沉淀——动态规划之其它背包问题与卡特兰数(leetcode真题剖析)

算法沉淀——动态规划之其它背包问题与卡特兰数 二维费用的背包问题01.一和零02.盈利计划 似包非包组合总和 Ⅳ 卡特兰数不同的二叉搜索树 二维费用的背包问题 01.一和零 题目链接&#xff1a;https://leetcode.cn/problems/ones-and-zeroes/ 给你一个二进制字符串数组 strs…...

利用最小二乘法找圆心和半径

#include <iostream> #include <vector> #include <cmath> #include <Eigen/Dense> // 需安装Eigen库用于矩阵运算 // 定义点结构 struct Point { double x, y; Point(double x_, double y_) : x(x_), y(y_) {} }; // 最小二乘法求圆心和半径 …...

OpenLayers 可视化之热力图

注&#xff1a;当前使用的是 ol 5.3.0 版本&#xff0c;天地图使用的key请到天地图官网申请&#xff0c;并替换为自己的key 热力图&#xff08;Heatmap&#xff09;又叫热点图&#xff0c;是一种通过特殊高亮显示事物密度分布、变化趋势的数据可视化技术。采用颜色的深浅来显示…...

Java多线程实现之Callable接口深度解析

Java多线程实现之Callable接口深度解析 一、Callable接口概述1.1 接口定义1.2 与Runnable接口的对比1.3 Future接口与FutureTask类 二、Callable接口的基本使用方法2.1 传统方式实现Callable接口2.2 使用Lambda表达式简化Callable实现2.3 使用FutureTask类执行Callable任务 三、…...

页面渲染流程与性能优化

页面渲染流程与性能优化详解&#xff08;完整版&#xff09; 一、现代浏览器渲染流程&#xff08;详细说明&#xff09; 1. 构建DOM树 浏览器接收到HTML文档后&#xff0c;会逐步解析并构建DOM&#xff08;Document Object Model&#xff09;树。具体过程如下&#xff1a; (…...

Caliper 配置文件解析:config.yaml

Caliper 是一个区块链性能基准测试工具,用于评估不同区块链平台的性能。下面我将详细解释你提供的 fisco-bcos.json 文件结构,并说明它与 config.yaml 文件的关系。 fisco-bcos.json 文件解析 这个文件是针对 FISCO-BCOS 区块链网络的 Caliper 配置文件,主要包含以下几个部…...

Spring AI与Spring Modulith核心技术解析

Spring AI核心架构解析 Spring AI&#xff08;https://spring.io/projects/spring-ai&#xff09;作为Spring生态中的AI集成框架&#xff0c;其核心设计理念是通过模块化架构降低AI应用的开发复杂度。与Python生态中的LangChain/LlamaIndex等工具类似&#xff0c;但特别为多语…...

Spring数据访问模块设计

前面我们已经完成了IoC和web模块的设计&#xff0c;聪明的码友立马就知道了&#xff0c;该到数据访问模块了&#xff0c;要不就这俩玩个6啊&#xff0c;查库势在必行&#xff0c;至此&#xff0c;它来了。 一、核心设计理念 1、痛点在哪 应用离不开数据&#xff08;数据库、No…...

Device Mapper 机制

Device Mapper 机制详解 Device Mapper&#xff08;简称 DM&#xff09;是 Linux 内核中的一套通用块设备映射框架&#xff0c;为 LVM、加密磁盘、RAID 等提供底层支持。本文将详细介绍 Device Mapper 的原理、实现、内核配置、常用工具、操作测试流程&#xff0c;并配以详细的…...

LeetCode - 199. 二叉树的右视图

题目 199. 二叉树的右视图 - 力扣&#xff08;LeetCode&#xff09; 思路 右视图是指从树的右侧看&#xff0c;对于每一层&#xff0c;只能看到该层最右边的节点。实现思路是&#xff1a; 使用深度优先搜索(DFS)按照"根-右-左"的顺序遍历树记录每个节点的深度对于…...

离线语音识别方案分析

随着人工智能技术的不断发展&#xff0c;语音识别技术也得到了广泛的应用&#xff0c;从智能家居到车载系统&#xff0c;语音识别正在改变我们与设备的交互方式。尤其是离线语音识别&#xff0c;由于其在没有网络连接的情况下仍然能提供稳定、准确的语音处理能力&#xff0c;广…...