springboot发送邮件,内容使用thymeleaf模板引擎排版

springboot发送邮件,内容使用thymeleaf模板引擎排版

      • 1、导入jar包
      • 2、yml设置
      • 3、收件人以及收件信息设置
      • 4、发邮件service
      • 5、模版页面
      • 6、controller

1、导入jar包

<!--发送邮件--><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-mail</artifactId></dependency>
<!--使用thymeleaf 形式--><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-thymeleaf</artifactId></dependency>

2、yml设置

发件邮箱信息设置:


spring:mail:host: smtp.xx.cnport: 465username: 你的邮箱password: 你的密码
#    default-encoding: UTF-8protocol: smtpproperties: # 配置以SSL的方式发送, 这个需要使用这种方式并且端口是465mail:smtp:auth: truessl:enable: truesocketFactory:class: com.sun.mail.util.MailSSLSocketFactoryfallback: falsedebug: true

3、收件人以及收件信息设置

@Getter
@Setter
public class AcceptMailParam {//标题private String title;//接收人邮件地址private String receiveEmail[];//抄送人邮件地址private String chaoSongPersonEmail[];//附件,value 文件的绝对地址/动态模板数据private Map<String, Object> attachment;//thymeleaf模版引擎页面对象数据:邮件排版内存List<OperateDataResultInfoView> pageViewList;
}页面对象数据展示
@Setter
@Getter
public class OperateDataResultInfoView {private Long id;/*** 存储当前年月,eg:202301*/private Integer curMonth;/*** 库名*/private String dbName;/*** 表名*/private String tableName;/*** 计划生成数据量*/private Long planGenDataCnt;/*** 实际生成数据量*/private Long actualGenDataCnt;/*** 备注*/private String remark;private String gmtCreate;private String gmtModified;/* ** 剩余待生成数据量*/private Long remainToGenCnt;/* ** 生成数据成功率(实际生成数量/计划生成数量),单位%*/private BigDecimal genDataSuccessRate;/**模拟生成数据*/public OperateDataResultInfoView() {this.id = ThreadLocalRandom.current().nextLong(100L, 999L);this.curMonth = DateUtil.getPreMonth();String[] dbAndTableName = ("dbName" + id + ".tableName" + id).split("\\.");this.dbName = dbAndTableName[0];this.tableName = dbAndTableName[1];this.planGenDataCnt = id + ThreadLocalRandom.current().nextLong(10L, 99L);this.actualGenDataCnt = id;this.remark = null;this.gmtCreate = DateUtil.getNowStr();this.gmtModified = DateUtil.getNowStr();this.remainToGenCnt = (planGenDataCnt - actualGenDataCnt) >= 0 ? (planGenDataCnt - actualGenDataCnt) : 0;BigDecimal rate = new BigDecimal(actualGenDataCnt).divide(new BigDecimal(planGenDataCnt), 4, BigDecimal.ROUND_HALF_UP);this.genDataSuccessRate = rate.compareTo(new BigDecimal("1")) >= 0 ? new BigDecimal("100") : rate.multiply(new BigDecimal("100")).setScale(2, BigDecimal.ROUND_HALF_UP);}
}

4、发邮件service

public interface SendMailService {/*** 邮件内容排版调试*/AcceptMailParam getMailContentAndSendMail(Integer curMonth);
}/*** 获取指定月份的邮件【邮件内容:生成数据的结果集 信息】* 次月1日8点 发送*/@Overridepublic AcceptMailParam getMailContentAndSendMail(Integer curMonth) {AcceptMailParam acceptMailParam = new AcceptMailParam();List<OperateDataResultInfoView> pageViewList = new ArrayList<>();for (int i = 0; i < 10; i++) {pageViewList.add(new OperateDataResultInfoView());}Collections.sort(pageViewList, Comparator.comparing(OperateDataResultInfoView::getId).reversed());acceptMailParam.setPageViewList(pageViewList);String[] emails = {"xxx1@qq.com"};String[] chaoSongPerson = {"xx2@qq.com"};//收件人,支持多人acceptMailParam.setReceiveEmail(emails);//抄送人,支持多人acceptMailParam.setChaoSongPersonEmail(chaoSongPerson);acceptMailParam.setTitle("统计业务表生成数据结果");//添加附件Map<String, Object> map = new HashMap<>();//key为邮件附件文件名称,路径改为你的服务器路径即可,可添加不同类型文件map.put("1-test1.zip", "/Users/gina/xx/data/test2.zip");map.put("2-test2.xlsx", "/Users/gina/xx/data/test1.xlsx");acceptMailParam.setAttachment(map);//调试邮件内容排版时,此处可注释掉。//this.sendTemplateMail(acceptMailParam,"/mail/list");return acceptMailParam;}

5、模版页面

在resources下,在路径templates/mail/下添加文件list.html

<!DOCTYPE html><html xmlns:th="http://www.thymeleaf.org"><style>tr.odd td {background-color: #f0faaa;}td.number {text-align: right;}table {width: 100%;border: 1px solid #000;border-collapse: collapse;}table > tbody > tr > td, table > thead > tr > th {padding: 2px 10px;border-left: 1px dotted #000000;vertical-align: top;line-height: 20px;}table > tbody > tr, table > thead > tr {border-bottom: 1px solid #000000;}table th {background-color: #99cc33;}table > tbody > tr > td > a, table > tbody > tr > td > a:hover {text-decoration: none;font-weight: bold;background-color: #352726;padding: 2px 10px;color: #f0faaa;margin-left: 10px;text-transform: uppercase;border: 0px;}</style><head><title>统计业务表生成数据结果</title><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /></head><body><h1>统计业务表生成数据结果</h1><table><tr><th>生成月份</th><th>库名</th><th>表名</th><th>计划生成()</th><th>实际生成()</th><th>成功率%</th><th>未生成()</th><th>创建时间</th><th>更新时间</th><th>备注</th></tr><tr th:each="o : ${pageViewList}" th:class="${o.id % 2 == 0}? 'odd'" ><td th:text="${o.curMonth}"   ></td><td th:text="${o.dbName}" ></td><td th:text="${o.tableName}" ></td><td th:text="${o.planGenDataCnt}" ></td><td th:text="${o.actualGenDataCnt}"></td><td th:text="${o.genDataSuccessRate}"></td><td th:text="${o.remainToGenCnt}"></td><td th:text="${o.gmtCreate}"></td><td th:text="${o.gmtModified}"></td><td th:text="${o.remark}"></td></tr></table></body>
</html>

6、controller

@Controller
@Slf4j
public class SendMailController {/*** 调试生成的页面样式,不发邮件* 数据处理结果集view*/@Resourceprivate SendMailService sendMailService;/** 点此可直接访问* http://localhost:8081/sendMail?curMonth=202311*/@RequestMapping("sendMail")public String sendMail(Model model, @RequestParam(name = "curMonth") Integer curMonth) {try {AcceptMailParam acceptMailParam = sendMailService.getMailContentAndSendMail(curMonth);model.addAttribute("title", acceptMailParam.getTitle());model.addAttribute("pageViewList", acceptMailParam.getPageViewList());} catch (Exception e) {log.error("sendMail fail ,msg={}", e.getMessage());}return "mail/list";}
}

7、启动服务后,访问页面展示:
在这里插入图片描述

邮箱内容样式为:
在这里插入图片描述

有对thymeleaf感兴趣的同学可通过中文官网去了解:thymeleaf中文官网

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

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

相关文章

react经验7:高亮关键字

预期效果&#xff1a; 实现原理 将需要高亮的关键词做成正则表达式 new RegExp((${word}), "gi")使用上述正则表达式切割目标字符串 origin.split(new RegExp((${word}), "gi"))切割结果会包含正则匹配到的词 过滤掉空字符&#xff0c;并对关键词包裹…

人工智能与大数据的紧密联系

随着科技的飞速发展&#xff0c;人工智能&#xff08;Artificial Intelligence&#xff0c;AI&#xff09;和大数据&#xff08;Big Data&#xff09;已成为当今社会的热门话题。人工智能在许多领域的应用越来越广泛&#xff0c;而大数据则提供了支持和驱动AI技术的巨大资源。本…

未来应用从何而来:认知力延伸、边界突破、回归云与产业

文 | 智能相对论 作者 | 沈浪 或许&#xff0c;谁也没想到未来应用来的如此之快&#xff0c;现如今传统应用从开发到体验&#xff0c;已经进入了一个前所未有的颠覆性改革阶段。 不久前&#xff0c;美国人工智能公司OpenAI举办开发者大会。在现场&#xff0c;公司创始人Sam …

BearPi Std 板从入门到放弃 - 先天神魂篇(6)(RT-Thread 按键中断响应)

简介 使用BearPi IOT Std开发板及主板自带两颗按键与用户灯, 实现按键触发中断控制灯亮灯灭 主板: 主芯片: STM32L431RCT6 LED : PC13 \ 推挽输出\ 高电平点亮 串口: Usart1 KEY1 : PB2 \ 上拉 \ 按下下降沿触发(一次)/上下沿触发(两次&#xff0c;实现按下开、松开关) KEY2 :…

FIFO的Verilog设计(三)——最小深度计算

文章目录 前言一、FIFO的最小深度写速度快于读速度写速度等于或慢于读速度 二、 举例说明1. FIFO写时钟为100MHz&#xff0c;读时钟为80Mhz情况一&#xff1a;一共需要传输2000个数据&#xff0c;求FIFO的最小深度情况二&#xff1a;100个时钟写入80个数据&#xff0c;1个时钟读…

PostgreSQL向量数据插件--pgvector安装(附PostgreSQL安装)

PostgreSQL向量数据插件--pgvector安装 一、版本二、数据库安装1. 在官网下载PostgreSQL14.0的安装包2.增加用户postgres3.解压安装 三、pgvector安装1. 从github上克隆下来2. 安装pgvector插件3. 开始使用pgvector启用pgsql命令行创建扩展 本文为本人在安装pgvector中踩过的坑…

25 redis 中 cluster 集群的工作模式

前言 我们这里首先来看 redis 这边实现比较复杂的 cluster集群模式 整个 cluster集群 中会包含多对 MasterSlave 的组合, 然后这多对 MasterSlave 来分解 16384 个 slot 然后 客户端这边 set, get 的时候, 先根据 key 计算对应存储的 slot, 然后 服务器这边响应 MOVED 目标…

P with Spacy:自定义文本分类管道

一、说明 Spacy 是一个功能强大的 NLP 库&#xff0c;其中许多 NLP 任务&#xff08;如标记化、词干提取、词性标记和命名实体解析&#xff09;均通过预训练模型提供开箱即用的功能。所有这些任务都由管道对象以及逐步应用于给定文本的不同函数的内部抽象来包装。该管道可以通过…

Android--UML类图使用详解

明敕星驰封宝剑&#xff0c;辞君一夜取楼兰 一&#xff0c;定义 类图(Class diagram)是显示了模型的静态结构&#xff0c;特别是模型中存在的类、类的内部结构以及它们与其他类的关系等。类图不显示暂时性的信息。类图是面向对象建模的主要组成部分。它既用于应用程序的系统分…

【数字电路】MacBook使用iverilog进行数字电路仿真

安装流程 在终端中用brew包管理工具进行安装仿真工具&#xff1a; 编译verilog代码&#xff1a; brew install icarus-verilog编译verilog代码&#xff1a; brew install verilatorMacOS系统显示UNIX GUI brew install xquartz可视化仿真波形图&#xff1a; brew install gtk…

基于Springboot的任务发布平台设计与实现(源码齐全+调试)

项目描述 临近学期结束&#xff0c;还是毕业设计&#xff0c;你还在做java程序网络编程&#xff0c;期末作业&#xff0c;老师的作业要求觉得大了吗?不知道毕业设计该怎么办?网页功能的数量是否太多?没有合适的类型或系统?等等。你想解决的问题&#xff0c;今天给大家介绍…

t-io 程序执行后,jvm不退出的原因

基于t-io 1.7.3 版本分析源码 1、设定当前时间&#xff0c;每10毫秒执行一次 (非守护线程) 2、对应线程池的核心线程在AioServer启动时全部激活&#xff0c;并且添加空任务到阻塞队列&#xff0c;让核心线程(非守护线程)一直存活

IO流学习

IO流:存储和读取数据的解决方案 import java.io.FileOutputStream; import java.io.IOException;public class Test {public static void main(String[] args) throws IOException {//1.创建对象//写出 输入流 OutputStream//本地文件fileFileOutputStream fos new FileOutputS…

RNN和LSTM学习笔记-初学者

提示&#xff1a; 目录 前言一、RNN介绍二、LSTM介绍总结 前言 提示&#xff1a; 提示&#xff1a; 一、RNN介绍 RNN是一种短时记忆&#xff0c;而LSTM是长短时记忆网络 二、LSTM介绍 总结

【专题】最小生成树(prim算法、kruscal算法)

目录 一、最小生成树二、Prim算法1. 算法思想2. 例题3. 性能分析 三、Kruscal算法1. 算法思想2. 例题3. 性能分析 一、最小生成树 生成树中边的权值&#xff08;代价&#xff09;之和最小的树。 二、Prim算法 1. 算法思想 设N(V,{E})是连通网&#xff0c;TE是N上最小生成树…

数据库02-04 中级SQL

01.on关键字&#xff1a; 主要用join…on来用多关系查询&#xff0c;和where关键字的相同 student关系&#xff1a; takes关系&#xff1a; 02.一般外连接 自然连接&#xff1a; 这个外连接&#xff08;自然连接&#xff09;会缺少空值的元祖&#xff08;本例子中的stude…

算法--数据结构基础

文章目录 数据结构单链表栈表达式求值前缀表达式中缀表达式后缀表达式 队列单调栈单调队列KMPTrie并查集堆哈希表字符串哈希 数据结构 单链表 用数组模拟&#xff08;静态链表&#xff09;效率比定义Node类&#xff08;动态链表&#xff09;效率高些 使用数组模拟单链表&am…

Java 使用mybatis的BaseTypeHandler实现数据自动AES加密解密,通过Hutool工具类自定义注解实现数据脱【附有完整步骤和代码】

一、AES加密 1 加密工具类 使用KeyGenerator生成AES算法生成器 public class AESUtil {/*** 密钥长度: 128, 192 or 256*/private static final int KEY_SIZE 256;/*** 加密/解密算法名称*/private static final String ALGORITHM "AES";/*** 随机数生成器&#…

【CDP】CDP 集群通过Knox 访问Yarn Web UI,无法跳转到Flink Web UI 问题解决

一、前言 记录下在CDP 环境中&#xff0c;通过Knox 访问Yarn Web UI&#xff0c;无法跳转到Flink Web UI 的BUG 解决方法。 二、问题复现 登录 Knox Web UI 找到任一 Flink 任务 点击 ApplicationMaster 跳转 Flink WEB UI 出问题 内容空白&#xff0c;无法正常跳转到…

JS基本语法

JS基本语法 变量数据类型原始数据类型 函数定义第一种方式第二种方式 JS 对象ArrayStringJavaScript 自定义对象JSONDOMBOM JS 事件事件监听事件绑定常见事件 变量 数据类型 原始数据类型 函数定义 第一种方式 第二种方式 JS 对象 Array String JavaScript 自定义对象 JSON …