Java使用企业邮箱发送预警邮件

news2024/10/7 8:25:17

前言:最近接到一个需求,需要根据所监控设备的信息,在出现问题时发送企业微信进行预警。

POM依赖

<!--  邮件   -->
<dependency>
   <groupId>com.sun.mail</groupId>
   <artifactId>jakarta.mail</artifactId>
   <version>1.6.7</version>
</dependency>

yml配置项 

mail:
    service:
        smtpSslEnable: true
        smtpAuth: true
        smtpHost: smtp.exmail.qq.com # 企业微信的host
        smtpPort: 465
        account: 发信人邮箱名
        password: 发信人邮箱密码

邮箱工具类

import lombok.Data;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component;

@Data
@Component
@ConfigurationProperties(prefix = "mail.service")
public class MailServiceProperties {

    private String account;


    /**
     * 登录密码
     */
    private String password;


    /**
     * 邮件服务器地址
     */
    private String smtpHost;


    /**
     * 发信端口
     */
    private String smtpPort;


    /**
     * 是否认证
     */
    private String smtpAuth;


    private String smtpSslEnable;


}
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import lombok.experimental.Accessors;

@Data
@AllArgsConstructor
@NoArgsConstructor
@Accessors(chain = true)
public class MailContent {
    private String aliasName;
    private String recipients;
    private String subject;
    private String content;
}
import com.ruoyi.common.config.MailServiceProperties;
import com.ruoyi.common.constant.MailContent;
import com.sun.mail.util.MailSSLSocketFactory;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import javax.activation.DataHandler;
import javax.activation.FileDataSource;
import javax.mail.*;
import javax.mail.internet.InternetAddress;
import javax.mail.internet.MimeBodyPart;
import javax.mail.internet.MimeMessage;
import javax.mail.internet.MimeMultipart;
import java.io.File;
import java.io.InputStream;
import java.nio.file.Files;
import java.nio.file.StandardCopyOption;
import java.security.GeneralSecurityException;
import java.util.Date;
import java.util.Properties;


@Slf4j
@Component
public class MailUtils {

    @Autowired
    private MailServiceProperties properties;

    /**
     * 批量发送邮件
     *
     * @param aliasName 别名
     * @param subject   主题
     * @param content   内容
     */
    public void batchSendEmail(String recipientList, String aliasName, String subject, String content) {
        if (!StringUtils.isEmpty(recipientList)) {
            String[] arrs = recipientList.split(",");
            for (String arr : arrs) {
                send(new MailContent(aliasName, arr, subject, content));
            }
        } else {
            log.error("收件人为空,发送失败。");
        }
    }

    /**
     * 批量发送邮件 带图片
     *
     * @param aliasName 别名
     * @param subject   主题
     * @param content   内容
     * @param  is       图片
     */
    public void batchSendEmail(String recipientList, String aliasName, String subject, String content,InputStream is) {
        if (!StringUtils.isEmpty(recipientList)) {
            String[] arrs = recipientList.split(",");
            for (String arr : arrs) {
                send(new MailContent(aliasName, arr, subject, content),is);
            }
        } else {
            log.error("收件人为空,发送失败。");
        }
    }

    /**
     * 发送邮件
     *
     * @param content
     */

    private void send(MailContent content) {
        // 设置邮件属性
        Properties prop = new Properties();
        prop.setProperty("mail.transport.protocol", "smtp");
        prop.setProperty("mail.smtp.host", properties.getSmtpHost());
        prop.setProperty("mail.smtp.port", properties.getSmtpPort());
        prop.setProperty("mail.smtp.auth", properties.getSmtpAuth());
        prop.setProperty("mail.smtp.ssl.protocols", "TLSv1.2");
        MailSSLSocketFactory sslSocketFactory = null;
        try {
            sslSocketFactory = new MailSSLSocketFactory();
            sslSocketFactory.setTrustAllHosts(true);
        } catch (GeneralSecurityException e1) {
            log.error("开启 MailSSLSocketFactory 失败", e1);
        }
        if (sslSocketFactory == null) {
            log.error("开启 MailSSLSocketFactory 失败");
        } else {
            prop.put("mail.smtp.ssl.enable", properties.getSmtpSslEnable());
            prop.put("mail.smtp.ssl.socketFactory", sslSocketFactory);
            // 创建邮件会话(注意,如果要在一个进程中切换多个邮箱账号发信,应该用 Session.getInstance)
            Session session = Session.getDefaultInstance(prop, new MyAuthenticator(properties.getAccount(), properties.getPassword()));
            try {
                MimeMessage mimeMessage = new MimeMessage(session);
                // 设置发件人别名(如果未设置别名就默认为发件人邮箱)
                if (content.getAliasName() != null && !content.getAliasName().trim().isEmpty()) {
                    mimeMessage.setFrom(new InternetAddress(properties.getAccount(), content.getAliasName()));
                } else {
                    mimeMessage.setFrom(new InternetAddress(properties.getAccount(), properties.getAccount()));
                }
                // 设置主题和收件人、发信时间等信息
                mimeMessage.addRecipient(Message.RecipientType.TO, new InternetAddress(content.getRecipients()));
                mimeMessage.setSubject(content.getSubject());
                mimeMessage.setSentDate(new Date());

                // 添加正文信息
                MimeMultipart multipart = new MimeMultipart();
                MimeBodyPart body = new MimeBodyPart();
                body.setContent(content.getContent(), "text/html; charset=UTF-8");
                multipart.addBodyPart(body);

                mimeMessage.setContent(multipart);
                // 开始发信
                mimeMessage.saveChanges();
                Transport.send(mimeMessage);
            } catch (Exception e) {
                log.error("发送邮件错误:", e);
            }
        }
    }

    /**
     * 发送邮件(带图片)
     *
     * @param content 文本内容
     * @param inputStream 图片内容
     */

    private void send(MailContent content, InputStream inputStream) {
        // 设置邮件属性
        Properties prop = new Properties();
        prop.setProperty("mail.transport.protocol", "smtp");
        prop.setProperty("mail.smtp.host", properties.getSmtpHost());
        prop.setProperty("mail.smtp.port", properties.getSmtpPort());
        prop.setProperty("mail.smtp.auth", properties.getSmtpAuth());
        prop.setProperty("mail.smtp.ssl.protocols", "TLSv1.2");
        MailSSLSocketFactory sslSocketFactory = null;
        try {
            sslSocketFactory = new MailSSLSocketFactory();
            sslSocketFactory.setTrustAllHosts(true);
        } catch (GeneralSecurityException e1) {
            log.error("开启 MailSSLSocketFactory 失败", e1);
        }
        if (sslSocketFactory == null) {
            log.error("开启 MailSSLSocketFactory 失败");
        } else {
            prop.put("mail.smtp.ssl.enable", properties.getSmtpSslEnable());
            prop.put("mail.smtp.ssl.socketFactory", sslSocketFactory);
            // 创建邮件会话(注意,如果要在一个进程中切换多个邮箱账号发信,应该用 Session.getInstance)
            Session session = Session.getDefaultInstance(prop, new MyAuthenticator(properties.getAccount(), properties.getPassword()));
            try {
                MimeMessage mimeMessage = new MimeMessage(session);
                // 设置发件人别名(如果未设置别名就默认为发件人邮箱)
                if (content.getAliasName() != null && !content.getAliasName().trim().isEmpty()) {
                    mimeMessage.setFrom(new InternetAddress(properties.getAccount(), content.getAliasName()));
                } else {
                    mimeMessage.setFrom(new InternetAddress(properties.getAccount(), properties.getAccount()));
                }
                // 设置主题和收件人、发信时间等信息
                mimeMessage.addRecipient(Message.RecipientType.TO, new InternetAddress(content.getRecipients()));
                mimeMessage.setSubject(content.getSubject());
                mimeMessage.setSentDate(new Date());

                // 添加正文信息
                MimeMultipart multipart = new MimeMultipart();


                //邮件内容
                //准备图片数据
                MimeBodyPart image=new MimeBodyPart();
                File tmpFile =File.createTempFile("123",".jpg");
                Files.copy(inputStream,tmpFile.toPath(), StandardCopyOption.REPLACE_EXISTING);
                DataHandler dh=new DataHandler(new FileDataSource(tmpFile));
                image.setDataHandler(dh);
                //id自己设置
                image.setContentID("123");
                //image.setFileName("999.png");

                //正文
                MimeBodyPart text=new MimeBodyPart();
                text.setContent(content.getContent()+"<br/><a><img src='cid:123'></a>","text/html;charset=UTF-8");
                // text.setContent("<h1 style='color:red'>带图片的邮件<img src='cid:bz.jpg'></h1>","text/html;charset=UTF-8");

                MimeMultipart mmTextImage = new MimeMultipart();
                mmTextImage.addBodyPart(text);
                mmTextImage.addBodyPart(image);
                // 关联关系
                mmTextImage.setSubType("related");

                MimeBodyPart textImage = new MimeBodyPart();
                textImage.setContent(mmTextImage);

                multipart.addBodyPart(textImage);
                multipart.setSubType("mixed");

                mimeMessage.setContent(multipart);
                // 开始发信
                mimeMessage.saveChanges();
                Transport.send(mimeMessage);
                tmpFile.deleteOnExit();
            } catch (Exception e) {
                log.error("发送邮件错误:", e);
            }
        }
    }

    /**
     * 认证信息
     */
    static class MyAuthenticator extends Authenticator {

        /**
         * 用户名
         */
        String username = null;

        /**
         * 密码
         */
        String password = null;

        /**
         * 构造器
         *
         * @param username 用户名
         * @param password 密码
         */
        public MyAuthenticator(String username, String password) {
            this.username = username;
            this.password = password;
        }

        @Override
        protected PasswordAuthentication getPasswordAuthentication() {
            return new PasswordAuthentication(username, password);
        }
    }

}

Controller

import com.ruoyi.common.core.domain.R;
import com.ruoyi.common.utils.MailUtils;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
@RequestMapping("/aicut")
@Slf4j
public class MailController {

    @Autowired
    private MailUtils mailUtils;

    @PostMapping("/sendMail")
    public R sendMail() {
        String recipientList = "xxx@xx.com"; //收件人邮箱,以逗号分割,可同时发给多个人
        String aliasName = "测试邮件";
        String subject = "邮件主题";
        String content = "邮件内容";

        mailUtils.batchSendEmail(recipientList, aliasName, subject, content);
        return R.ok();
    }
}

测试结果

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

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

相关文章

电脑开机启动项在哪里设置?优化系统速度不是梦!

电脑的开机启动项设置直接影响着系统启动的速度和性能&#xff0c;合理配置启动项可以提高系统的启动速度&#xff0c;同时确保开机时运行的程序符合个人需求。那么&#xff0c;电脑开机启动项在哪里设置呢&#xff1f;本文将详细介绍电脑开机启动项设置的三种方法&#xff0c;…

harmony 鸿蒙系统学习 安装ohpm报错 ohpm install failed

一. 安装配置 DevEco Studio 安装包时报错 execute ohpm install failed. Install task failed: ArkTS 3.2.12.5. Install ArkTS dependencies failed. 解决办法 找原因&#xff0c;首先&#xff0c;我的电脑中之前安装过node&#xff0c;也许是因为这个。&#xff08;其实…

CMake与vs的配置对应(常规->附加包含目录,链接器->输入)

常规->附加包含目录 对应CMake的 include_directories(${QT_PATH}/include) 写在 add_executable 前面 链接器->输入 对应CMake的 target_link_libraries(${PROJECT_NAME} xx.lib) 写在 add_executable 后面

文献阅读:在整个小鼠大脑中,细胞类型的高分辨率转录组和空间图谱

文献介绍 「文献题目」 A high-resolution transcriptomic and spatial atlas of cell types in the whole mouse brain 「研究团队」 曾红葵&#xff08;Allen 脑科学研究所&#xff09; 「发表时间」 2023-03-06 「发表期刊」 Nature 「影响因子」 64.8 「DOI」 10.1038/…

基于PSO优化的CNN多输入时序回归预测(Matlab)粒子群算法优化卷积神经网络时序回归预测

目录 一、程序及算法内容介绍&#xff1a; 基本内容&#xff1a; 亮点与优势&#xff1a; 二、实际运行效果&#xff1a; 三、部分代码&#xff1a; 四、完整程序下载&#xff1a; 一、程序及算法内容介绍&#xff1a; 基本内容&#xff1a; 本代码基于Matlab平台编译&…

掌握这8大工具,自媒体ai写作之路畅通无阻! #经验分享#科技#媒体

这些宝藏AI 写作神器&#xff0c;我不允许你还不知道~国内外免费付费都有&#xff0c;还有AI写作小程序分享&#xff0c;大幅度提高写文章、写报告的效率&#xff0c;快来一起试试吧&#xff01; 1.元芳写作 这是一个微信公众号 面向专业写作领域的ai写作工具&#xff0c;写作…

C#,数值计算,矩阵的乔莱斯基分解(Cholesky decomposition)算法与源代码

一、安德烈路易斯乔尔斯基 安德烈路易斯乔尔斯基出生于法国波尔多以北的查伦特斯海域的蒙古扬。他在波尔多参加了Lyce e&#xff0c;并于1892年11月14日获得学士学位的第一部分&#xff0c;于1893年7月24日获得第二部分。1895年10月15日&#xff0c;乔尔斯基进入莱科尔理工学院…

Java Web(六)--XML

介绍 官网&#xff1a;XML 教程 为什么需要&#xff1a; 需求 1 : 两个程序间进行数据通信&#xff1f;需求 2 : 给一台服务器&#xff0c;做一个配置文件&#xff0c;当服务器程序启动时&#xff0c;去读取它应当监听的端口号、还有连接数据库的用户名和密码。spring 中的…

git使用过的命令记录

目录 git add .git commit --amendgit push -f origin HEAD:mastergit checkout .git stash想把某个pr的修改应用到本地git 撤销&#xff0c;放弃本地修改参考文档 git add . 将本地修改提交到暂存区 git commit --amend 将修改的东西 追加到上一个pr git push -f origin H…

SQL数据库基础语法-查询语句

SQL数据库基础语法-查询语句 Group By #对数据进行分组 >select name,count(id) from student group by name; #查询name字段人数&#xff0c;cont函数进行计数 >select * from users group by users; >select * from users where id1 group by 2; >select * from …

线阵相机参数介绍之轴编码器控制

1.1 功能介绍 编码器是将检测对象的运动与相机拍摄取图相匹配的设备&#xff0c;也即检测对象运动一定距离&#xff0c;相机就拍摄一定行高的图像。 编码器会将检测对象的实际位移转换为固定数量电信号。例如&#xff1a;编码器的精度是2000p/r,该参数的含义是编码器每转一圈输…

webpack打包速度优化思维导图

webpack打包速度优化思维导图 前言附件 前言 去年的时候公司一个项目体积过大&#xff0c;我是m1芯片的macpro&#xff0c;光启动就要1分钟&#xff0c;配置差点都电脑&#xff0c;启动就要3分钟&#xff0c;自然打包速度也会慢很多&#xff0c;我们是gitlab设置成了自动打包的…

数据分析 — 电商用户分析和用户 RFM 模型

目录 一、电商用户分析1、数据字段信息2、数据读取3、数据清洗4、可视化分析1、每年销售额的增长情况2、各个地区分店的销售额3、每个分店每一年的销售额4、销售淡旺季5、新增用户 二、RFM 模型1、RFM 模型的三个维度2、RFM 的客户类型标签3、RFM 模型的二分法思想4、代码 一、…

【算法】动态规划1,最小花费爬楼梯,解码方法

一、动态规划简介 动态规划 , 英文名称 Dynamic Programming , 简称 DP , 不是具体的某种算法 , 是一种算法思想 ; 动态规划 , 没有具体的步骤 , 只有一个核心思想 ; 动态规划 的 核心思想 是 由大化小 , 大规模问题 使用 小规模问题 计算结果 解决 , 类似于 分治算法 ; 二、…

ipad作为扩展屏的最简单方式(仅需在同一局域网下,无需数据线)

ipad和win都下载安装toDesk&#xff0c;并且都处于同一局域网下 连接ipad&#xff0c;在ipad中输入win设备的设备密码和临时密码&#xff0c;连接上后可以看到ipad会是win屏幕的镜像&#xff0c;此时退出连接&#xff0c;准备以扩展模式再次连接。 注意&#xff0c;如果直接从…

SOPHON算能科技新版SDK环境配置以及C++ demo使用过程

目录 1 SDK大包下载 2 获取SDK中的库文件和头文件 2.1 注意事项 2.2 交叉编译环境搭建 2.2.1 首先安装工具链 2.2.2 解压sophon-img包里的libsophon_soc__aarch64.tar.gz&#xff0c;将lib和include的所有内容拷贝到soc-sdk文件夹 2.2.3 解压sophon-mw包里的sophon-mw-s…

pyqt如何实现拖拽打开文件(通过windows的快捷方式打开文件)

桌面端的开发中如何通过windows的快捷方式打开文件&#xff0c;那么如何将需要打开的数据传递给qt程序呢&#xff1f; 研究了一下发现很简单 通过sys.argv可以轻松的实现传参 sys.argv import sys print(sys.argv)这个方法可以获取系统传递给程序的参数&#xff0c;默认是个列…

Android 12.0 systemui锁屏页面时钟显示样式的定制功能实现

1.前言 在12.0的系统ROM定制化开发中,在进行systemui的相关开发中,当开机完成后在锁屏页面就会显示时间日期的功能,由于 开发产品的需求要求时间显示周几上午下午接下来就需要对锁屏显示时间日期的相关布局进行分析,然后实现相关功能 效果图如图: 2.systemui锁屏页面时钟显…

Linux搭建JavaEE环境

Linux搭建JavaEE环境 需要在 Linux 下进行 JavaEE 的开发&#xff0c;我们需要安装如下软件 JDKtomcatmysqlidea 安装JDK 安装步骤 首先去官网下载jdk的linux版本 下载地址&#xff1a;https://www.oracle.com/cn/java/technologies/downloads/ 1) mkdir /opt/jdk 2) 通过 …

视频推拉流EasyDSS视频直播点播平台授权出现激活码无效并报错400是什么原因?

视频推拉流EasyDSS视频直播点播平台集视频直播、点播、转码、管理、录像、检索、时移回看等功能于一体&#xff0c;可提供音视频采集、视频推拉流、播放H.265编码视频、存储、分发等视频能力服务&#xff0c;在应用场景上&#xff0c;平台可以运用在互联网教育、在线课堂、游戏…