spring boot发送邮箱,java实现邮箱发送(邮件带附件)3中方式【保姆级教程一,代码直接用】

news/2025/1/12 23:11:10/

文章目录

      • Java发送邮箱的方式
        • 1. 基于 Javax.mail 实现
          • 关于附件上传的方法
        • 2. 基于 org.apache.commons.mail 实现
          • 常见报错
        • 3. 基于 spring-boot-starter-mail 实现(推荐)

实际开发时需要实现邮件发送,本文章实现如何从零实现邮件发送。也就是 Spring Boot 项目中如何实现邮箱发送。

Java发送邮箱的方式

1、前提:需要获取发件人邮箱的授权码,也就是打开POP3/IMAP/SMTP服务设置,拿到授权码。

2、获取到邮件服务器的 smtp 地址:

服务商smtp服务地址smtp服务端口pop3服务地址pop3服务端口
新浪: sina.comsmtp.sina.com.cn25pop3.sina.com.cn110
搜狐:sohu.comsmtp.sohu.com25pop3.sohu.com110
163:163.comsmtp.163.com25smtp.163.com110
QQ:qq.comsmtp.qq.com25 或 465 或 587smtp.qq.com110
foxmail:foxmail.comsmtp.foxmail.com25pop3.foxmail.com110
QQ企业邮箱:exmail.qq.comsmtp.exmail.qq.com995pop3.exmail.qq.com587/465
1. 基于 Javax.mail 实现

先引入依赖:

<dependency><groupId>javax.mail</groupId><artifactId>mail</artifactId><version>1.4.7</version>
</dependency>

大致的流程:

1、创建配置项变量 Properties 对象,用于声明 smtp 相关配置;

2、创建一个Session,重写一个Authenticator,用于声明发件人邮箱地址和授权码;

3、利用 session 创建一个 MimeMessage 对象,再利用 MimeMessage 创建一个 MimeMessageHelper 对象,该对象用于设置收件人、发件人、抄送、秘密抄送、主题、内容、附件、发送时间等属性;

4、利用 Transport.send 方法发送邮件。

代码示例:

java">@Slf4j
public class EmailJavax {// 也可以从配置文件中取值// smtp服务地址private static final String senderSmtpHost = "smtp.qq.com";// 邮箱端口号private static final String senderSmtpPort = "465";// 发信人邮箱private static final String senderEmail = "xxx@qq.com";// 发信人邮箱授权码private static final String senderPassword = "xxx";/*** 邮件发送** @param subject              邮件主题* @param content              邮件内容* @param contentIsHtml        内容是否为html格式* @param fromMailPersonalName 发件人昵称* @param toMail               收件人邮箱* @param ccMail               抄送人邮箱* @param bccMail              秘密抄送人邮箱* @param fileNames            文件名(本地路径)*/public static void sendEmail(String subject, String content, boolean contentIsHtml, String fromMailPersonalName, String toMail, String ccMail, String bccMail, List<String> fileNames) throws GeneralSecurityException, UnsupportedEncodingException, MessagingException {// 1.创建配置项变量,用于声明 smtp 相关配置Properties properties = System.getProperties();// smtp服务地址properties.put("mail.smtp.host", senderSmtpHost);// smtp服务端口properties.put("mail.smtp.port", senderSmtpPort);// 开启验证properties.put("mail.smtp.auth", "true");// 开启TLS加密properties.put("mail.smtp.starttls.enable", "true");// 是否启用socketFactory,默认为trueproperties.put("mail.smtp.socketFactory.fallback", "true");MailSSLSocketFactory sf = new MailSSLSocketFactory();sf.setTrustAllHosts(true);properties.put("mail.smtp.ssl.enable", "true");properties.put("mail.smtp.ssl.socketFactory", sf);// 2.重写Authenticator,用于声明发件人邮箱地址和授权码// 建立会话,将邮箱授权码给jvmSession session = Session.getDefaultInstance(properties, new Authenticator() {@Overrideprotected PasswordAuthentication getPasswordAuthentication() {return new PasswordAuthentication(senderEmail, senderPassword);}});// 设置为true可以在控制台打印发送过程,生产环境关闭session.setDebug(true);// 3.创建MimeMessage对象// 创建邮件对象MimeMessage message = new MimeMessage(session);// 创建MimeMessageHelper对象,通过MimeMessageHelper设置正文和附件,否则会导致两者显示不全MimeMessageHelper helper = new MimeMessageHelper(message, true, "utf-8");//设置发件人helper.setFrom(new InternetAddress(senderEmail, fromMailPersonalName));// 设置收件人,to为收件人,cc为抄送,bcc为密送if (StringUtils.isEmpty(toMail)) {log.error("邮件收件人为空");return;}helper.setTo(InternetAddress.parse(toMail, false));if (!StringUtils.isEmpty(ccMail)) {helper.setCc(InternetAddress.parse(ccMail, false));}if (!StringUtils.isEmpty(bccMail)) {helper.setBcc(InternetAddress.parse(bccMail, false));}// 设置邮件主题helper.setSubject(subject);//设置邮件正文内容helper.setText(content, contentIsHtml);//设置发送的日期helper.setSentDate(new Date());// 设置附件(注意这里的fileName必须是服务器本地文件名,不能是远程文件链接)if (!CollectionUtils.isEmpty(fileNames)) {for (String fileName : fileNames) {FileDataSource fileDataSource = new FileDataSource(fileName);helper.addAttachment(fileDataSource.getName(), fileDataSource);}}// 4.调用Transport的send方法去发送邮件Transport.send(message);}
}
java">// 测试:
public class Test(){public static void main(String[] args) throws MessagingException, GeneralSecurityException, UnsupportedEncodingException {// excel表格的存放位置:String fileName = "/xx/xx/xx/供应商接口参数.xlsx";String html = "<h1>统计数据如下所示:</h1>" +"<table border=\"1\">\n" +"  <tr>\n" +"    <th>月度销售额</th>\n" +"    <th>年度销售额</th>\n" +"  </tr>\n" +"  <tr>\n" +"    <td>10000</td>\n" +"    <td>2000000</td>\n" +"  </tr>\n" +"</table>";// 调方法:EmailJavax.sendEmail("统计数据", html, true, "发送人名字", "收件人邮箱", null, null, Collections.singletonList(fileName));}
}
关于附件上传的方法

附件上传有多种方式,除了上面用到的 FileDataSource 形式添加附件外,还有 文件、输入流的方式添加:

  • addAttachment(String attachmentFilename, DataSource dataSource)
  • addAttachment(String attachmentFilename, File file)
  • addAttachment(String attachmentFilename, InputStreamSource inputStreamSource)
  • addAttachment(String attachmentFilename, InputStreamSource inputStreamSource, String contentType)
2. 基于 org.apache.commons.mail 实现

commons 包中提供了 Email 抽象类,该类下实现了

  • HtmlEmail(用于HTML正文,附件邮件发送)
  • ImageHtmlEmail(用于HTML图片正文,附件邮件发送)
  • MultiPartEmail(用于附件邮件发送)
  • SimpleEmail(用于简单邮件发送)

其继承关系如图所示:

1、引入依赖:

<dependency><groupId>org.apache.commons</groupId><artifactId>commons-email</artifactId><version>1.5</version>
</dependency>

2、实现:

java">@Slf4j
public class EmailCommons {// 也可以从配置文件中取值// smtp服务地址private static final String senderSmtpHost = "smtp.qq.com";// 邮箱端口号private static final String senderSmtpPort = "465";// 发信人邮箱private static final String senderEmail = "xxx@qq.com";// 发信人邮箱授权码private static final String senderPassword = "xxx";/*** 邮件发送** @param subject              邮件主题* @param content              邮件内容* @param contentIsHtml        内容是否为html格式* @param fromMailPersonalName 发件人昵称* @param toMail               收件人邮箱* @param ccMail               抄送人邮箱* @param bccMail              秘密抄送人邮箱* @param fileList             附件            */public static void sendEmail(String subject, String content, boolean contentIsHtml, String fromMailPersonalName, String toMail, String ccMail, String bccMail, File[] fileList) throws GeneralSecurityException, UnsupportedEncodingException, MessagingException {// 1.创建HtmlEmail对象HtmlEmail email = new HtmlEmail();// smtp服务地址email.setHostName(senderSmtpHost);// smtp服务端口email.setSmtpPort("mail.smtp.port", senderSmtpPort);email.setCharset("utf-8");// 邮件验证email.setAuthentication(senderEmail,senderPassword);//设置发件人email.setFrom(senderEmail, fromMailPersonalName);// 设置收件人,to为收件人,cc为抄送,bcc为密送if (StringUtils.isEmpty(toMail)) {log.error("邮件收件人为空");return;}email.addTo(toMail);if (!StringUtils.isEmpty(ccMail)) {email.addCc(ccMail);}if (!StringUtils.isEmpty(bccMail)) {email.addBcc(bccMail);}// 设置邮件主题email.setSubject(subject);//设置邮件正文内容if(contentIsHtml){email.setHtmlMsg(content);}else{email.setMsg(content);}// 设置附件if(!ObjectUtils.isEmpty(fileList)){for (File file : fileList) {EmailAttachment emailAttachment = new EmailAttachment();emailAttachment.setName(MimeUtility.encodeText(file.getName()));emailAttachment.setPath(file.getPath());email.attach(emailAttachment);}}// 4.调用send方法去发送邮件email.send();}
}

3、测试:

java">public class Test(){public static void main(String[] args) throws MessagingException, GeneralSecurityException, UnsupportedEncodingException {// excel表格的存放位置:String fileName = "/xx/xx/xx/供应商接口参数.xlsx";File file = new File(fileName);String html = "<h1>统计数据如下所示:</h1>" +"<table border=\"1\">\n" +"  <tr>\n" +"    <th>月度销售额</th>\n" +"    <th>年度销售额</th>\n" +"  </tr>\n" +"  <tr>\n" +"    <td>10000</td>\n" +"    <td>2000000</td>\n" +"  </tr>\n" +"</table>";EmailCommons.sendEmail("统计数据", html, true, "发送人名字", "收件人邮箱", null, null,new File[]{file} );}
}
常见报错

1、535 Login Fail. Please enter your authorization code to login

原因:邮箱验证设置的账号密码错误

解决:注意参数值正确性:email.setAuthentication(发件人邮箱地址,邮箱授权码);

2、MessagingException: Got bad greeting from SMTP host: smtp.qq.com, port: 465, response: [EOF]

解决:commons.mail 发送邮件时,QQ 邮箱使用默认端口 25 即可

3. 基于 spring-boot-starter-mail 实现(推荐)

1、引入依赖:

<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-mail</artifactId>
</dependency>

2、使用配置文件:

spring:# 配置发送邮件的配置信息mail:# 配置smtp服务主机地址host: smtp.qq.com# 发送者邮箱username: XXX@qq.com# 配置密码,注意不是真正的密码,而是申请到的授权码password: jlpXXXXXdecj# 端口号:465或587port: 465# 默认的邮件编码为UTF-8default-encoding: UTF-8# 其他参数properties:mail:# 配置SSL 加密工厂smtp:ssl:# 本地测试,先放开sslenable: truerequired: true# 开启debug模式,这样邮件发送过程的日志会在控制台打印出来,方便排查错误debug: true

3、实现:

java">/*** 发送邮件类*/
public class SendEmailUtil {// 注入系统相关类@Autowiredprivate JavaMailSender javaMailSender;@Autowiredprivate MailProperties mailProperties;// 发送者邮箱
//    @Value("${spring.mail.username}")
//    private String sendMailer;/*** 邮件发送1** @param subject              邮件主题* @param content              邮件内容* @param contentIsHtml        内容是否为html格式* @param fromMailPersonalName 发件人昵称* @param toMail               收件人邮箱* @param ccMail               抄送人邮箱* @param bccMail              秘密抄送人邮箱* @param fileNames            文件名(本地文件名)*/public static void sendEmail(String subject, String content, boolean contentIsHtml, String fromMailPersonalName,String toMail, String ccMail, String bccMail, List<String> fileNames) throws MessagingException, UnsupportedEncodingException {// true 代表支持复杂的类型MimeMessage mimeMessage = javaMailSender.createMimeMessage();MimeMessageHelper helper = new MimeMessageHelper(mimeMessage, true);/* 邮件发信人:两种写法:1. 定义成员变量获取application.yml的username属性@Value("${spring.mail.username}")private String sendMailer;helper.setFrom(sendMailer,发件人名称)2. 注入系统类的对象,然后调方法获取,获取的值也是application.yml文件中的值@Autowiredprivate MailProperties mailProperties;helper.setFrom(mailProperties.getUsername(),发件人名称);*/helper.setFrom(mailProperties.getUsername(), fromMailPersonalName);// 邮件收信人  1或多个helper.setTo(toMail);if (!ObjectUtils.isEmpty(ccMail)) {// 邮件抄送人helper.setCc(ccMail);}if (!ObjectUtils.isEmpty(bccMail)) {// 邮件私密抄送人helper.setBcc(bccMail);}// 邮件主题helper.setSubject(subject);// 邮件内容   contentIsHtml值为 true 代表支持htmlhelper.setText(content, contentIsHtml);// 设置附件(注意这里的fileName必须是服务器本地文件名,不能是远程文件链接)if (!CollectionUtils.isEmpty(fileNames)) {for (String fileName : fileNames) {// 添加邮件附件FileDataSource fileDataSource = new FileDataSource(fileName);helper.addAttachment(fileDataSource.getName(), fileDataSource);}}// 发送邮件javaMailSender.send(mimeMessage);}/*** 邮件发送2 -- 方法优化 -- 文件对象** @param subject              邮件主题* @param content              邮件内容* @param contentIsHtml        内容是否为html格式* @param fromMailPersonalName 发件人昵称* @param toMail               收件人邮箱* @param ccMail               抄送人邮箱* @param bccMail              秘密抄送人邮箱* @param files                文件对象*/public static void sendEmail(String subject, String content, boolean contentIsHtml, String fromMailPersonalName,String toMail, String ccMail, String bccMail, File[] files) throws MessagingException, UnsupportedEncodingException {MimeMessage message = javaMailSender.createMimeMessage();MimeMessageHelper helper = new MimeMessageHelper(message, true);helper.setFrom(mailProperties.getUsername(), fromMailPersonalName);helper.setTo(toMail);if (!ObjectUtils.isEmpty(ccMail)) {helper.setCc(ccMail);}if (!ObjectUtils.isEmpty(bccMail)) {helper.setBcc(bccMail);}helper.setSubject(subject);helper.setText(content, contentIsHtml);// 设置附件,不能是远程文件if (!ObjectUtils.isEmpty(files)) {for (File file : files) {helper.addAttachment(file.getName(), file);}}javaMailSender.send(message);}/*** 邮件发送3 -- 方法优化 -- 使用流** @param subject              邮件主题* @param content              邮件内容* @param contentIsHtml        内容是否为html格式* @param fromMailPersonalName 发件人昵称* @param toMail               收件人邮箱* @param ccMail               抄送人邮箱* @param bccMail              秘密抄送人邮箱* @param fileName             文件名称* @param fileInput            文件流*/public static void sendEmail(String subject, String content, boolean contentIsHtml, String fromMailPersonalName,String toMail, String ccMail, String bccMail, String fileName, InputStreamSource fileInput) throws MessagingException, UnsupportedEncodingException {MimeMessage message = javaMailSender.createMimeMessage();MimeMessageHelper helper = new MimeMessageHelper(message, true);helper.setFrom(mailProperties.getUsername(), fromMailPersonalName);helper.setTo(toMail);if (!ObjectUtils.isEmpty(ccMail)) {helper.setCc(ccMail);}if (!ObjectUtils.isEmpty(bccMail)) {helper.setBcc(bccMail);}helper.setSubject(subject);helper.setText(content, contentIsHtml);// 设置附件,不能是远程文件if (fileInput != null) {helper.addAttachment(fileName, fileInput);}javaMailSender.send(message);}
}

关于邮件发送的方法参数: 上面几个方法,最后接收附件的参数都不一样,说明可以灵活变化

  • sendEmail(xxx, List<String> fileNames):可以接收多个附件,其中传的时候,就是附件的绝对路径
  • sendEmail(xxx, File[] files):可以接收多个附件,传的时候,就是附件的文件对象
  • sendEmail(xxx, InputStreamSource fileInput):接收一个附件,传的时候,就是附件的流

5、测试:

java">/*** excel表格生成工具*/
public class ExcelUtil {/*** 生成excel文件** @param fileName excel文件路径* @param dataList 数据列表* @param clazz    导出对象类* @param <T>* @return*/public static <T> File generateExcel(String fileName, List<T> dataList, Class<T> clazz) {// 生成文件File file = new File(fileName);// 单sheet写入EasyExcel.write(file, clazz).sheet("XXX").doWrite(dataList);return file;}/*** 生成excel文件 -- 方法优化 -- 用流** @param dataList 数据列表* @param clazz 导出对象类* @param <T>* @return*/public static <T> ByteArrayOutputStream generateExcel(List<T> dataList, Class<T> clazz) {ByteArrayOutputStream out = new ByteArrayOutputStream();// 单excel写入EasyExcel.write(out, clazz).sheet("XXX").doWrite(dataList);return out;}}
java">public class Test(){public static void main(String[] args) throws MessagingException, GeneralSecurityException, UnsupportedEncodingException {String content = "客户统计数据如附件所示";// 测试邮件发送1// excel表格的存放位置:String fileName = "/xx/xx/xx/供应商接口参数.xlsx";String html = "<h1>统计数据如下所示:</h1>" +"<table border=\"1\">\n" +"  <tr>\n" +"    <th>月度销售额</th>\n" +"    <th>年度销售额</th>\n" +"  </tr>\n" +"  <tr>\n" +"    <td>10000</td>\n" +"    <td>2000000</td>\n" +"  </tr>\n" +"</table>";SendEmailUtil.sendEmail("统计数据", html, true, "发送人名字", "收件人邮箱", null, null, Arrays.asList(fileName));// 测试邮件发送2File excel = ExcelUtil.generateExcel("文件名", 表格映射的实体类对象, 表格映射的实体类.class);SendEmailUtil.sendEmail("统计数据", content, false, "发送人名字", "收件人邮箱", null, null, new File[]{excel});// 测试邮件发送3ByteArrayOutputStream bos = ExcelUtil.generateExcel(userInfos, UserInfo.class);SendEmailUtil.sendEmail("统计数据", content, false, "发送人名字", "收件人邮箱", null, null, fileName, new ByteArrayResource(bos.toByteArray()));}
}

注意: 实现 excel 生成,然后发送邮箱 的代码,可以查看这篇文章:生成 excel 并发送邮箱

至此!文章的内容结束!!记得关注收藏,有更多精彩内容!!!


http://www.ppmy.cn/news/1562628.html

相关文章

使用 Docker 构建 preboot 交叉编译环境

ASR1606/ASR1603 的 preboot 代码需要在 Linux 环境下编译&#xff0c;通常使用 VMware 或者 VirtualBox 软件创建一个 Linux 虚拟机&#xff0c;在虚拟机中做交叉编译。但 preboot 不是那种需要经常编译的代码&#xff0c;完全可以将 preboot 的编译环境制作成 docker 镜像&am…

TCP通信原理学习

TCP三次握手和四次挥手以及为什么_哔哩哔哩_bilibili

【设计模式】介绍常见的设计模式

&#x1f970;&#x1f970;&#x1f970;来都来了&#xff0c;不妨点个关注叭&#xff01; &#x1f449;博客主页&#xff1a;欢迎各位大佬!&#x1f448; 文章目录 ✨ 介绍一下常见的设计模式✨ Spring 中常见的设计模式 这期内容主要是总结一下常见的设计模式&#xff0c;可…

应急响应之入侵排查(下)

一.进程排查 1.Windows 任务管理器查看 在 Windows 系统中&#xff0c;可通过任务管理器查看进程信息。操作步骤为&#xff1a;在任务管理器界面&#xff0c;于 “查看” 选项中选择 “选择列”&#xff0c;随后添加 “映像路径名称” 和 “命令行”&#xff0c;以此查看更多进…

探索 Oracle 数据库:核心概念与实践指南

Oracle 数据库是业界领先的关系型数据库管理系统 (RDBMS)&#xff0c;广泛应用于企业级应用和大型数据处理。本文将深入探讨 Oracle 数据库的核心概念、常用功能以及最佳实践&#xff0c;帮助你更好地理解和使用 Oracle 数据库。 1. Oracle 数据库的核心概念 1.1 体系结构 O…

Android中Activity

一、AndroidManifest中的<activity>标签 <activity>标签在AndroidManifest.xml文件中用于定义和配置应用中的每一个Activity。Activity是Android应用的基本构建块之一&#xff0c;主要负责展示用户界面&#xff0c;并处理用户与之的交互。每个在应用中显示给用户的…

抖音生活服务举办直营服务商年度峰会 服务商支付交易额同比涨85%

1月7日&#xff0c;抖音生活服务在海南三亚举办了“服务无界&#xff0c;卓越领航”直营服务商年度峰会&#xff0c;公布了过去一年在服务商生态建设的举措与成果&#xff0c;并分享了新一年平台在战略经营方向、产品功能升级以及营销拓展等方面的规划布局。同时&#xff0c;为…

spring task使用

Spring Task 简介 Spring Task 是 Spring 框架原生自带的任务调度框架&#xff0c;它犹如一把瑞士军刀&#xff0c;为开发者提供了丰富多样的功能&#xff0c;助力轻松创建和管理定时任务。相较于其他一些第三方任务调度框架&#xff0c;Spring Task 最大的优势在于其与 Sprin…