SpringBoot 发送邮件(四十三)

news2024/11/28 10:46:53

从头开始,并不意味着失败,相反,正是拥抱成功的第一步,即使还会继续失败

上一章简单介绍了 SpringBoot 整合 ES (四十二), 如果没有看过,请观看上一章

一. 发送邮件

关于发送邮件的功能和基础知识,老蝴蝶这儿就不重点讲解了。

一.一 前期准备, 获取邮件相应的信息

以 QQ 邮箱为例子, 首先登录 QQ邮箱 web 端, 点击设置

image-20230516173441967

image-20230516173648246

https://wx.mail.qq.com/account/index?sid=zYdOWYytOXku61hLAExYZgAA#/

在安全设置—> 生成授权码

image-20230516174110965

image-20230516174124643

扫描发送短信后,就会生成授权码, 是一个 字符串。

一.二 发送邮件的依赖

发送邮件 使用 spring-boot-starter-mail 依赖 的 org.springframework.mail.javamail.JavaMailSender 类

 <!--添加 email 邮件发送-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-mail</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-velocity</artifactId>
            <version>1.4.7.RELEASE</version>
        </dependency>

一.三 application.yml 配置信息

spring:
  # 配置发送邮件# 配置发送邮件
  mail:
    host: smtp.qq.com # smtp.qq.com 对应的ip
    username: Xxxxx@qq.com
    password: Xxxx
    port: 465
    default-encoding: utf-8
    protocol: smtp
    properties:
      mail:
        smtp:
          auth: true
          starttls:
            enable: true
            required: true
          ssl:
            enable: true
            socketFactory:
              port: 465
              class: javax.net.ssl.SSLSocketFactory

一.四 发送邮件接口和相应的服务

二. 邮件发送

		@Value("${spring.mail.username}")
	private String from;
	@Resource
	private JavaMailSender javaMailSender;

二.一 发送普通的文本

二.一.一 接口

	/**
	 * 发送普通的文本消息
	 *
	 * @param toArr   发送人, 之间用 ,号分隔
	 * @param subject 发送主题
	 * @param content 发送的内容, 普通文本内容
	 */
	boolean sendSimpleMail(String[] toArr, String subject, String content);

二.一.二 接口实现

	@Override
	public boolean sendSimpleMail(String[] toArr, String subject, String content) {
		SimpleMailMessage simpleMailMessage = new SimpleMailMessage();
		simpleMailMessage.setTo(toArr);
		simpleMailMessage.setSubject(subject);
		simpleMailMessage.setText(content);
		simpleMailMessage.setFrom(from);
		// 发送时间
		simpleMailMessage.setSentDate(new Date());
		//发送信息
		try {
			javaMailSender.send(simpleMailMessage);
			return true;
		} catch (Exception e) {
			log.error("componentAndSendReqeust simple mail error", e);
			return false;
		}
	}

二.一.三 测试

    @Test
    public void simpleEmailTest() {
        String[] toArr = new String[]{"1290513799@qq.com"};
        emailService.sendSimpleMail(toArr, "发送测试简单文件", "一封简单的测试文件");
        log.info(">>>发送邮件成功");
    }

image-20230516174755005

二.二 发送 html 消息

二.二.一 接口

	/**
	 * 发送 HTML 消息
	 *
	 * @param toArr   发送人, 之间用 ,号分隔
	 * @param subject 发送主题
	 * @param content 发送的内容 ,html 形式
	 */
	boolean sendHtmlMail(String[] toArr, String subject, String content);

二.二.二 接口实现

		@Override
	public boolean sendHtmlMail(String[] toArr, String subject, String content) {
		MimeMessage mimeMessage = javaMailSender.createMimeMessage();
		try {
			MimeMessageHelper mimeMessageHelper = new MimeMessageHelper(mimeMessage, true);
			mimeMessageHelper.setTo(toArr);
			mimeMessageHelper.setSubject(subject);
			mimeMessageHelper.setText(content, true);
			mimeMessageHelper.setFrom(from);
			//发送信息
			javaMailSender.send(mimeMessage);
			return true;
		} catch (MessagingException e) {
            log.error("componentAndSendReqeust mail error ", e);
			return false;
		}
	}

二.二.三 测试

      @Test
    public void htmlEmailTest() {
        String[] toArr = new String[]{"1290513799@qq.com"};
        emailService.sendHtmlMail(toArr, "发送测试HTML文件", "<a href='https://wwww.baidu.com'>百度</a>");
        log.info(">>>发送邮件成功");
    }

image-20230516174911647

二.三 发送 携带附件的 邮件

二.三.一 接口

	/**
	 * 发送 携带附件的邮件
	 * @param toArr   发送人, 之间用 ,号分隔
	 * @param subject 发送主题
	 * @param content 发送的内容 ,html 形式
	 * @param filePaths 附件路径地址集合
	 * @return
	 */
	boolean sendAttachmentsMail(String[] toArr, String subject, String content,
								List<String> filePaths);

二.三.二 接口实现

	/**
	 * 附件邮件
	 * @param toArr 接收者邮件
	 * @param subject 邮件主题
	 * @param content HTML内容
	 * @param filePaths 附件路径
	 */
	@Override
	public boolean sendAttachmentsMail(String[] toArr, String subject, String content,
									   List<String> filePaths) {
		MimeMessage message = javaMailSender.createMimeMessage();
		try {

			MimeMessageHelper helper = new MimeMessageHelper(message, true);
			helper.setTo(toArr);
			helper.setSubject(subject);
			helper.setText(content, true);
			helper.setFrom(from);

			if (!CollectionUtils.isEmpty(filePaths)){
				for (String filePath : filePaths) {
					FileSystemResource file = new FileSystemResource(new File(filePath));
					String fileName = file.getFilename();
					// 可以添加多个复杂
					helper.addAttachment(fileName, file);
				}
			}
			javaMailSender.send(message);
			return true;
		} catch (MessagingException e) {
			log.error("componentAndSendReqeust mail error ", e);
			return false;
		}
	}

二.三.三 测试

有两个图片文件

image-20230516175051869

     @Test
    public void sendAttachmentsMailTest() {
        String[] toArr = new String[]{"1290513799@qq.com"};
        emailService.sendAttachmentsMail(toArr, "发送附件文件", "<a href='https://wwww.baidu.com'>百度</a>",
                Arrays.asList("E:\\Alan\\logoold.jpg", "E:\\Alan\\logo.jpg"));
        log.info(">>>发送邮件成功");
    }

image-20230516175130108

二.四 模板邮件消息

一般我们发送给用户的邮件信息,都是一个固定的模板。 我们这里用 Velocity 模板

关于 Velocity 的使用, 可以看 老蝴蝶之前写的文章: SpringBoot整合Velocity(十二)

定义一个模板内容:

image-20230516175418411

二.四.一 模板邮件接口

	/**
	 * 发送邮件 velocity 模板邮件
	 *  @param toArr                发送人
	 * @param subject              主题
	 * @param dataMap              发送模板邮件填充数据
	 * @param templateName 模板名称
	 */
	boolean sendVelocityMail(String[] toArr, String subject, Map<String, Object> dataMap, String templateName);

二.四.二 模板接口实现

	private VelocityEngine velocityEngine;

	@PostConstruct
	public void initVelocityEngine() {
		velocityEngine = new VelocityEngine();
		Properties p = new Properties();
		velocityEngine.setProperty(RuntimeConstants.RESOURCE_LOADER, "classpath");
		velocityEngine.setProperty("classpath.resource.loader.class", ClasspathResourceLoader.class.getName());

		// 配置资源
		// velocityEngine.setProperty(RuntimeConstants.FILE_RESOURCE_LOADER_PATH, "/usr/local/templates/");
		velocityEngine.init(p);
	}

	@Override
    public boolean sendVelocityMail(String[] toArr, String subject, Map<String, Object> dataMap, String templateName) {
        try {
            String velocityMailText = getVelocityMailText(dataMap,templateName);
            return sendHtmlMail(toArr, subject, velocityMailText);
        } catch (Exception ex) {
            log.error(">>>componentAndSendReqeust email is error,", ex);
            return false;
        }
    }

    private String getVelocityMailText(Map<String, Object> dataMap, String templateName) {
        VelocityContext velocityContext = new VelocityContext(dataMap);
        StringWriter writer = new StringWriter();
        velocityEngine.mergeTemplate(templateName, "UTF-8", velocityContext, writer);
        return writer.toString();
    }

二.四.三 测试模板

@Test
    public void velocityTest() {
        String[] toArr = new String[]{"1290513799@qq.com"};
        Map<String, Object> dataMap = new HashMap<>();
        dataMap.put("line",System.lineSeparator());
        dataMap.put("title","你叫什么名称");
        dataMap.put("content","我叫岳泽霖,是一个快乐的程序员");
        emailService.sendVelocityMail(toArr, "发送velocity  文件", dataMap,"interface_tenwhy.vm" );
        log.info(">>>发送测试邮件成功");
    }

image-20230516175755948

发送邮件时,如果发送失败, 会抛出相应的异常。 如 发送人授权信息不对,接收人信息不对等。

image-20230516180021233

三. 其它邮件的配置

常见的还有 163 ,google 邮件

163 的配置

spring:
	mail:
        host: smtp.163.com
        port:
        username: xxxx@163.com
        password: ************

google 邮箱配置

spring:
	mail: 
		host: smtp.gmail.com
		port: 465
		username: xxxxx@gmail.com
		password: ****************

本章节的代码放置在 github 上:

https://github.com/yuejianli/springboot/tree/develop/SpringBoot_Email

谢谢您的观看,如果喜欢,请关注我,再次感谢 !!!

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

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

相关文章

NodeJs在Linux下使用的各种问题

环境:ubuntu16.04 ubuntu中安装NodeJs 通过apt-get命令安装后发现只能使用nodejs&#xff0c;而没有node命令 如果想避免这种情况请看下面连接的这种安装方式&#xff1a; 拓展见:Linux下Nodejs安装&#xff08;完整详细&#xff09; 如果想解决问题的话,输入下面的命令即可…

Sentinel-1的GRD和SLC数据的区别和联系

目录 01 前言 02 Sentinel1下载时的基本参数解释 2.1 卫星平台 2.2 产品类型 03 SLC数据和GRD数据的区别 3.1 处理过程的区别 3.2 处理操作的一点解释 3.2.1 为什么要做地形辐射校正&#xff1f; 3.2.2 多普勒地形校正和地形辐射校正的区别&#xff1f; 01 前言 最近…

【软考数据库】第十二章 事务管理

目录 12.1 事务的基本概念 12.2 数据库的并发控制 12.3 数据库的故障与恢复 12.3.1 事务故障 12.3.2 系统故障 12.3.3 介质故障 12.3.4 数据库备份 12.4 数据库的安全性与完整性 前言&#xff1a; 笔记来自《文老师软考数据库》教材精讲&#xff0c;精讲视频在b站&am…

B2B2C商城系统怎么挑选好?

B2B2C商城它不仅提供B2B模式下的批量交易&#xff0c;还为消费者提供了B2C模式的优质购物体验&#xff0c;因此&#xff0c;越来越多的企业或商家开始重视B2B2C商城系统的搭建&#xff0c;如目前的SHOP、Magento等商城系统。那么&#xff0c;如何挑选合适的B2B2C商城系统呢&…

接口自动化测试—如何实现多套环境的自动化测试?

在敏捷迭代的项目中&#xff0c;通常会将后台服务部署到多套测试环境。那么在进行接口自动化测试时&#xff0c;则需要将服务器的域名进行配置。使用一套接口测试脚本&#xff0c;通过切换域名地址配置&#xff0c;实现多套环境的自动化测试。 实战练习 分别准备两套测试环境…

ffmpeg合并多张图片为视频,加转场

需求是合并多个图片为视频&#xff0c;并在每个图片衔接处加入转场特效&#xff0c;第一种方式是用fade做转场&#xff0c;第二种方式是xfade做转场&#xff0c;xfade的转场特效更多&#xff0c;建议用这个。如果对你有帮助&#xff0c;点赞收藏。 第一种&#xff1a;直接用fa…

实验十 超市订单管理系统综合实验

实验十 超市订单管理系统综合实验 应粉丝要求&#xff0c;本博主帮助实现基本效果&#xff01; 未避免产生版权问题&#xff0c;本项目博主不公开源码&#xff0c;如果您遇到相关问题可私聊博主&#xff01; 一、实验目的及任务 通过该实验&#xff0c;掌握利用SSM框架进行系…

涂鸦智能幻彩灯带开发包,如何帮助开发者寻找创意?

如果你常看短视频&#xff0c;一定被各种炫酷的幻彩灯带产品刷屏过。随着智能幻彩灯带的问世&#xff0c;其玩法也愈加丰富。比如支持用户对灯带上的每一颗灯珠实现亮度和颜色的单独调节&#xff0c;并专属自定义你想要的场景模式&#xff0c;呈现出花式的动态灯光效果。 而且…

【采访】 | “标准化推动车辆诊断的质量和效率”

机动车产业/行业&#xff08;Mobility Industry&#xff09;的变化速度比以往任何时候都快&#xff0c;电动和替代驱动以及数字化和自动驾驶变得愈发重要&#xff0c;需要更为强大且智能的车辆。与此同时&#xff0c;E/E系统的复杂性也在不断增加&#xff0c;这对车载通信提出了…

Vue - el-form的学习记录 - 记录问题解决方法

问题1&#xff1a; Elementui在重置表单时&#xff0c;无法使用this.$refs[‘formRefVal‘].resetFields()清空表单数据&#xff1b; 必须为每一个 el-form-item 配置一个指定的 prop 参数&#xff0c;this.$refs[‘formRefVal‘].resetFields() 它会跟进初始值&#xff0c;还…

深入分析:香港 windows 和linux VPS 区别和使用需求

​  香港虚拟专用服务器 (VPS) 两种常见的操作类型是 Windows 和 Linux VPS。尽管两者都提供相似的好处&#xff0c;但两者之间的显著差异会影响哪一个更适合用户的特定需求。 在本文中&#xff0c;我们将探讨这两种解决方案之间的主要区别&#xff0c;包括它们的操作系统和软…

IM即时通讯系统[SpringBoot+Netty]——梳理(四)

文章目录 九、消息业务的核心之消息可达性、一致性、幂等性、实时性1、消息实时性—利用多线程解决消息串行的问题&#xff0c;提高处理效率2、消息实时性—校验逻辑前置由tcp通过feign接口提前校验3、消息实时性—利用mq异步持久化消息4、用了TCP就不会丢包、丢消息了吗&#…

【黄啊码】如何使用thinkphp结合wokerman实现分组群聊

大家好&#xff0c;我是黄啊码&#xff0c;关于php的课程咱们好像停更了一小段时间了&#xff0c;今天继续&#xff0c;讲讲怎么使用wokerman实现分组群聊&#xff0c;不知道怎么用tp搭建wokerman的&#xff0c;请看下边链接&#xff0c;我不会再做阐述&#xff1a;【黄啊码】w…

半监督医学图像分割的平滑性和类分离研究

文章目录 Exploring Smoothness and Class-Separation for Semi-supervised Medical Image Segmentation摘要本文方法Pixel-level SmoothnessInter-class Separation 实验结果 Exploring Smoothness and Class-Separation for Semi-supervised Medical Image Segmentation 摘要…

win10,win11 下部署Vicuna-7B,Vicuna-13B模型,gpu cpu运行

运行Vicuna-7B需要RAM>30GB或者14GB的显存 运行Vicuna-13B需要RAM>60GB或者28GB的显存 如果没有上面的硬件配置请绕行了&#xff0c;我笔记本有64G内存&#xff0c;两个都跑跑看&#xff0c;使用python3.9&#xff0c;当时转换13b时一直崩溃后来发现是没有设定虚拟内存&…

火爆B站的阿玮老师,他带着课程走来了(含4天入门到精通Java直播课)

他来啦、他来啦 终于把百万B站用户都爱的阿玮老师盼来啦&#xff01; 此处应该有掌声 如果你是B站资深用户 相信早就耳闻阿玮老师的大名啦 阿玮老师在B站有多受欢迎&#xff0c;你往下康康~~ 这究竟是什么神仙老师呀 来啦就出不去啦 听了阿玮老师的课 才发现 原来学习…

二分类结局变量Logistic回归临床模型预测(二)——单因素多因素logistic回归分析(二)

本节讲的是二分类结局变量的临床模型预测,与之前讲的Cox回归不同,https://lijingxian19961016.blog.csdn.net/article/details/124088364https://lijingxian19961016.blog.csdn.net/article/details/124088364https://lijingxian19961016.blog.csdn.net/article/details/1300…

Linux shell脚本 免交互

Here Document 免交互 使用I/O重定向的方式将命令列表提供给交互式程序或命令&#xff0c;比如 ftp、cat 或 read 命令。 是标准输入的一种替代品 可以帮助脚本开发人员不必使用临时文件来构建输入信息&#xff0c;而是直接就地生产出一个“文件”并用作“命令”的标准输入。 H…

《LeetCode》—— 买卖股票的最佳时机

本期&#xff0c;我将给大家讲解的是有关动态规划类的题——买卖股票的最佳时机。这个系列总共有四道题。接下来&#xff0c;让我们一起去看看&#xff01;&#xff01;&#xff01; 目录 &#xff08;一&#xff09;买卖股票的最佳时机 &#xff08;二&#xff09;买卖股票的…

应用案例 | 使用dataFEED OPC Tunnel解决基于DCOM的OPC Classic通信难题

一 背景 OPC&#xff08;OLE for Process Control&#xff09;Classic是一种基于COM&#xff08;Component Object Model&#xff09;的协议&#xff0c;用于在工业控制系统中实现数据通信和集成。它为工业自动化提供了一种标准接口&#xff0c;可使不同厂商的设备和系统之间进…