Java实现多附件的邮件发送
叙:本文主要记述了 Springboot 中如何集成并实现多附件的邮件发送,以QQ邮箱的服务器为发送邮件的邮件服务器;
Java实现多附件的邮件发送
1、前期准备
主要需要什么呢?
- 第一,你要知道你选择的作为发送邮件的邮箱账号所在服务器所提供的发送邮件服务器(一般都会有一个发送邮件服务器 [SMTP] 和接收邮件服务器 [POP3]);
- 第二,发送邮件服务器的端口号;
- 第三,你要针对发送邮件的邮箱设定 授权码,这个授权码就是第三方使用邮箱进行一系列操作时所需要登陆的密码;
1.1、获取收发服务器地址及其端口号
收发邮件服务器和端口号的整理都在此篇《各邮箱服务商的接收、发送邮件服务器地址、端口号》文章中,有兴趣的大家可以看看尝试一下不同的邮箱发送短信,想要学习一下自己去找这些的可以继续往下看;
第一步、第二步的获悉信息位置如下查找(QQ邮箱,其他的邮箱也差不多,有需要的可以去翻一下):
往下翻,找到下图中的设置,首先开启服务:IMAP/SMTP,通俗点说这个服务就是在开发过程中所使用的一种账号认证服务设置,打开后点击第四步~
点击了第四步中的连接后可以看到如下的页面,往下翻就会看到图中的圈住的信息了~
这一下就将我们所需要的三分之二的数据都找齐了,就剩下授权码了;
1.2、 授权码的获取
其实第三个就是上上张截图中第五步的操作,点击第五步的按钮链接,如下图所示:
使用上图中的密保手机给框中的号码【1069070069】发送一个内容为【配置邮件客户端】的信息,发送完后点击【我已发送】按钮,若是QQ邮箱的服务器收到了你发的短信,就会返给你个如下图所示的16位串(图是我偷的,我自己之前操作的我还记着呢,你们发吧,我随意~????????????),复制并保存一下这个串;
en~,前准备工作可以了,下面开始上代码;
2、代码
就不多余的叙述了,代码里面有注释,如果碰到麻烦的可能会罗嗦两句哈~
2.1、pom文件
<!-- javamail —— 邮箱jar --> <dependency> <groupId>javax.mail</groupId> <artifactId>mail</artifactId> <version>1.4.7</version> </dependency>
2.1、Controller层
此代码中若是大家无法在网上找到 "ResponseData" 的jar包,在此代码中亦可以不要,这只是个结果集封装的方法;
package com.java.product.module.controller;
import com.java.product.module.utils.MailSendUtil;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.macrocloud.kernel.model.reqres.response.ResponseData;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.multipart.MultipartFile;
@RestController@RequestMapping("/mail")
@Api(value = "邮件发送", tags = "发送邮件")
public class MailController {
/**
* 发送带附件的邮件
*
* @param sendMail 发件人邮箱
* @param sendMailPwd 发件人密码
* @param sendMailName 发件人昵称(可选)
* @param receiveMail 收件人邮箱
* @param receiveMailName 收件人昵称(可选)
* @param sendSMTPHost 发件人邮箱的 SMTP 服务器地址, 必须准确, 不同邮件服务器地址不同, 一般(只是一般, 绝非绝对)格式为: smtp.xxx.com
* @param title 邮件主题
* @param content 邮件正文
* @param files 上传的文件集合
* @param port 邮件服务器发送邮件端口
*/
@PostMapping("/sendFileMail")
@ApiOperation(value = "文件邮件", notes = "sendMail(发件人邮箱),sendMailPwd(发件人密码),sendMailName(发件人昵称-可选),receiveMail(收件人邮箱),receiveMailName(收件人昵称-可选),sendSMTPHost(发件人邮箱的SMTP服务器地址),title(邮件主题),content(邮件正文)")
public ResponseData sendFileMail(String sendMail, String sendMailPwd, String sendMailName, String[] receiveMail, String receiveMailName, String sendSMTPHost, String title, String content, MultipartFile[] files, String port) {
try{
MailSendUtil.sendFileMail(sendMail, sendMailPwd, sendMailName, receiveMail, receiveMailName, sendSMTPHost, title, content,files, port);
}catch (Exception e){
return ResponseData.error(e.toString());
}
return ResponseData.success();
}
}
Utils工具类
package com.java.product.module.utils;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.multipart.MultipartFile;
import javax.activation.DataHandler;
import javax.activation.DataSource;
import javax.mail.Authenticator;
import javax.mail.PasswordAuthentication;
import javax.mail.Session;
import javax.mail.Transport;
import javax.mail.internet.*;
import javax.mail.util.ByteArrayDataSource;
import java.io.ByteArrayInputStream;
import java.io.InputStream;
import java.util.Date;
import java.util.LinkedList;
import java.util.List;
import java.util.Properties;
import java.util.regex.Pattern;
/**
* @Author:qtl
* @Discription:邮件发送工具类
* @Date:11:00 2021/4/20
*/
@Slf4j
public class MailSendUtil {
/**
* 邮箱正则表达式
*/
static final Pattern pattern = Pattern.compile("^([a-zA-Z0-9_\\-\\.]+)@((\\[[0-9]{1,3}\\.[0-9]{1,3}\\.[0-9]{1,3}\\.)|(([a-zA-Z0-9\\-]+\\.)+))([a-zA-Z]{2,4}|[0-9]{1,3})(\\]?)$");
/**
* 发送带附件的邮件
*
* @param sendMail 发件人邮箱
* @param sendMailPwd 发件人密码(授权码)
* @param sendMailName 发件人昵称(可选)
* @param receiveMail 收件人邮箱
* @param receiveMailName 收件人昵称(可选)
* @param sendSMTPHost 发件人邮箱的 SMTP 服务器地址, 必须准确, 不同邮件服务器地址不同, 一般(只是一般, 绝非绝对)格式为: smtp.xxx.com
* @param title 邮件主题
* @param content 邮件正文
* @param files 附件文件集合
* @param port 邮件服务器发送邮件端口
*
*/
public static void sendFileMail(String sendMail, String sendMailPwd, String sendMailName, String[] receiveMail, String receiveMailName,
String sendSMTPHost, String title, String content, MultipartFile[] files, String port) {
Session session = createSSLSession(sendSMTPHost, port, sendMailName, sendMailPwd);
// 3. 创建一封邮件
MimeMessage message;
try {
message = createMimeMessage(session, sendMail, sendMailName, receiveMail, receiveMailName, title, content);
// 5. Content: 邮件正文(可以使用html标签)(内容有广告嫌疑,避免被邮件服务器误认为是滥发广告以至返回失败,请修改发送内容)
MimeMultipart mm = new MimeMultipart();
MimeBodyPart text = new MimeBodyPart();
text.setContent(content, "text/html;charset=UTF-8");
mm.addBodyPart(text);
if (files.length > 0) {
for (MultipartFile f : files) {
// MultipartFile 转化成 InputStream
byte [] byteArr=f.getBytes();
InputStream inputStream = new ByteArrayInputStream(byteArr);
MimeBodyPart attachment = new MimeBodyPart();
DataSource source = new ByteArrayDataSource(inputStream, "application/msexcel");
attachment.setDataHandler(new DataHandler(source));
// 设置附件的文件名(需要编码)
attachment.setFileName(MimeUtility.encodeText(f.getOriginalFilename()));
// 10. 设置文本和 附件 的关系(合成一个大的混合"节点" / Multipart )
// 如果有多个附件,可以创建多个多次添加
mm.addBodyPart(attachment);
}
}
message.setContent(mm);
message.saveChanges();
// 4. 根据 Session 获取邮件传输对象
Transport transport = session.getTransport("smtp");
transport.connect(sendSMTPHost, sendMail, sendMailPwd);
// 6. 发送邮件, 发到所有的收件地址, message.getAllRecipients() 获取到的是在创建邮件对象时添加的所有收件人, 抄送人, 密送人
transport.sendMessage(message, message.getAllRecipients());
// 7. 关闭连接
} catch (Exception e) {
log.error("", e);
}
}
/**
* 创建session
*/
private static Session createSSLSession(String sendSMTPHost, String port, String userName, String pwd) {
// 1. 创建参数配置, 用于连接邮件服务器的参数配置
Properties props = new Properties(); // 参数配置
props.setProperty("mail.smtp.user", userName);
props.setProperty("mail.smtp.password", pwd);
props.setProperty("mail.smtp.host", sendSMTPHost);
props.setProperty("mail.smtp.port", port);
props.setProperty("mail.smtp.socketFactory.class", "javax.net.ssl.SSLSocketFactory");
props.setProperty("mail.smtp.socketFactory.fallback", "false");
props.setProperty("mail.smtp.socketFactory.port", port);
props.put("mail.smtp.auth", "true");
// 2. 根据配置创建会话对象, 用于和邮件服务器交互
Session session = Session.getDefaultInstance(props, new Authenticator() {
//身份认证
@Override
protected PasswordAuthentication getPasswordAuthentication() {
return new PasswordAuthentication(userName, pwd);
}
});
session.setDebug(true); // 设置为debug模式, 可以查看详细的发送 log
return session;
}
/**
* 创建一封只包含文本的简单邮件
*
* @param session 和服务器交互的会话
* @param sendMail 发件人邮箱
* @param sendMailName 发件人昵称
* @param receiveMail 收件人邮箱
* @param receiveMailName 收件人昵称
* @param title 邮件主题
* @param content 邮件正文
* @return
* @throws Exception
*/
public static MimeMessage createMimeMessage(Session session, String sendMail, String sendMailName, String[] receiveMail, String receiveMailName, String title, String content) throws Exception {
// 1. 创建一封邮件
MimeMessage message = new MimeMessage(session);
// 2. From: 发件人
message.setFrom(new InternetAddress(sendMail, sendMailName, "UTF-8"));
// 3. To: 收件人(可以增加多个收件人、抄送、密送)
List<InternetAddress> to = new LinkedList<>();
for (String s : receiveMail) {
if (pattern.matcher(s).matches()) {
to.add(new InternetAddress(s));
}
}
//Address[] addresses = new Address[]{new InternetAddress(receiveMail),new InternetAddress(receiveMail)};
message.addRecipients(MimeMessage.RecipientType.TO, to.toArray((new InternetAddress[to.size()])));
// 4. Subject: 邮件主题(标题有广告嫌疑,避免被邮件服务器误认为是滥发广告以至返回失败,请修改标题)
message.setSubject(title, "UTF-8");
// 5. Content: 邮件正文(可以使用html标签)(内容有广告嫌疑,避免被邮件服务器误认为是滥发广告以至返回失败,请修改发送内容)
message.setContent(content, "text/html;charset=UTF-8");
// 6. 设置发件时间
message.setSentDate(new Date());
// 7. 保存设置
message.saveChanges();
return message;
}
}
3、 测试接口
在此解释一下哈,我没有用swagger来调试我的接口,可能很多人都很奇怪,为什么我配置了swagger但是却不用它呢?因为在swagger中,同一个集合中只能存在一个参数,也就是说我没法测多个文件同时上传的效果了,嘛~ !只能这样使用postMan了,下图中的参数如果觉得乱的,大家可以看一下controller层中的字段注释~
返回的数据结果说请求成功了,那么我登陆一下我的接收者账号,看看数据是否正常存在~
第一部至少成功了,就看里面的附件了;
OK,文件正常!一切正常~
4、上传文件管控
另外,存在一个下问题,既然涉及到了文件的上传,那就需要有个文件上传管控了,配置文件【application.yml】中加入如下代码:
spring: # 开启文件上传控制 servlet:multipart: enabled: true # 文件写入磁盘的阈值 file-size-threshold: 1KB # 最大文件大小 max-file-size: 10MB # 最大请求大小 max-request-size: 200MB
pass:文中有什么不明白的欢迎提问,共同努力,共同进步!
关注公众号
低调大师中文资讯倾力打造互联网数据资讯、行业资源、电子商务、移动互联网、网络营销平台。
持续更新报道IT业界、互联网、市场资讯、驱动更新,是最及时权威的产业资讯及硬件资讯报道平台。
转载内容版权归作者及来源网站所有,本站原创内容转载请注明来源。
-
上一篇
当我遇见Python——工作记事四则
4月14日的中午,偶然看到51CTO技术博客大赛,有奖品,就想参加一下,于是翻开日志整理出我实际工作中使用Python的四件事。本人在生产制造业担任运维工程师一职,平时的工作内容多而杂,维护业务系统的可用性和稳定性,数据的完整性和可靠性以及整个网络系统的安全性,总结一点就是大量的重复的苦逼运维工作,枯燥乏味,但是强烈的责任心告诉我少做或不做是不行的。于是,在最火的Python流行时,利用“摸鱼”时间稍微学习了一下Python,并使用Python处理了工作中的四件事,算是把学到的应用到实际工作中吧,在此感谢51CTO提供了非常好的学习平台,人生就是不断进步的过程,而51CTO就是助推前进的帮手。 1、利用Python批量修改图片名称。此案例是利用导入os模块进行文件名称的处理,大量的名称格式不统一的图片文件作为输入,经过Python生成的可执行工具进行快速处理后,输出为名称格式统一的图片文件,大量的复杂的重复的工作交给Python,这个得力“助手”处理快速又准确。有此期间帮我处理了大约八千张图片,可以说相当给力。 2、PyQt5实现每日自动备份交换机配置。网络设备配置备份工作对于网络工程...
-
下一篇
Java服务端支付宝对接(详细)
Java服务端支付宝对接(详细) 1、创建连接的公钥私钥 2、导入jar包、编写代码 3、使用测试工具测试 4、支付宝回调返回支付结果 1、创建连接的公钥私钥 支付宝对接时需要有相应的密钥、网关、APPID,第一步就是获取这些数据: 在支付宝【开发者服务中心】(https://openhome.alipay.com/platform/developerIndex.htm)网页中进行创建(测试时使用沙箱创建就好,不过使用这个需要先入驻平台,很简单,如下操作即可:) 然后进去后在控制台页面中渣都到【沙箱测试】: 进入沙箱后操作步骤如下: 然后进入支付宝密钥生成器下载页面下载即可: 下载下来后点击运行安装得到如下的一个应用: 点击进入并登录(注意,在【支付宝开发者服务中心】网页中登陆的支付宝账号必须和在此登陆的支付宝账号必须是同一个): 然后获取密钥: 将密钥什么的都保存下来,如果没保存也不用担心,本地会自动保你保存一份在你本地,如下所示: 然后将生成的公钥放到【开发者服务中心】的沙箱设置中,如下: 如此,第一步的操作算是完成! 2、导入jar包、编写代码 导入jar包如下(仅展示的时支付宝...
相关文章
文章评论
共有0条评论来说两句吧...










微信收款码
支付宝收款码