- ubuntu12.04环境下使用kvm ioctl接口实现最简单的虚拟机
- Ubuntu 通过无线网络安装Ubuntu Server启动系统后连接无线网络的方法
- 在Ubuntu上搭建网桥的方法
- ubuntu 虚拟机上网方式及相关配置详解
CFSDN坚持开源创造价值,我们致力于搭建一个资源共享平台,让每一个IT人在这里找到属于你的精彩世界.
这篇CFSDN的博客文章SpringBoot中发送QQ邮件功能的实现代码由作者收集整理,如果你对这篇文章有兴趣,记得点赞哟.
本文是vhr系列的第十二篇,项目地址https://github.com/lenve/vhr 。
邮件发送也是一个老生常谈的问题了,代码虽然简单,但是许多小伙伴对过程不太理解,所以还是打算和各位小伙伴聊聊这个话题.
邮件协议 。
我们经常会听到各种各样的邮件协议,比如smtp、pop3、imap,那么这些协议有什么作用,有什么区别?我们先来讨论一下这个问题.
smtp是一个基于tcp/ip的应用层协议,江湖地位有点类似于http,smtp服务器默认监听的端口号为25。看到这里,小伙伴们可能会想到既然smtp协议是基于tcp/ip的应用层协议,那么我是不是也可以通过socket发送一封邮件呢?回答是肯定的.
生活中我们投递一封邮件要经过如下几个步骤:
1.深圳的小王先将邮件投递到深圳的邮局 。
2.深圳的邮局将邮件运送到上海的邮局 。
3.上海的小张来邮局取邮件 。
这是一个缩减版的生活中邮件发送过程。这三个步骤可以分别对应我们的邮件发送过程,假设从aaa@qq.com发送邮件到111@163.com:
1.aaa@qq.com先将邮件投递到腾讯的邮件服务器 。
2.腾讯的邮件服务器将我们的邮件投递到网易的邮件服务器 。
3.111@163.com登录网易的邮件服务器查看邮件 。
邮件投递大致就是这个过程,这个过程就涉及到了多个协议,我们来分别看一下.
SMTP协议全称为Simple Mail Transfer Protocol,译作简单邮件传输协议,它定义了邮件客户端软件于SMTP服务器之间,以及SMTP服务器与SMTP服务器之间的通信规则。也就是说aaa@qq.com用户先将邮件投递到腾讯的SMTP服务器这个过程就使用了SMTP协议,然后腾讯的SMTP服务器将邮件投递到网易的SMTP服务器这个过程也依然使用了SMTP协议,SMTP服务器就是用来收邮件。而POP3协议全称为Post Office Protocol,译作邮局协议,它定义了邮件客户端与POP3服务器之间的通信规则,那么该协议在什么场景下会用到呢?当邮件到达网易的SMTP服务器之后,111@163.com用户需要登录服务器查看邮件,这个时候就该协议就用上了:邮件服务商都会为每一个用户提供专门的邮件存储空间,SMTP服务器收到邮件之后,就将邮件保存到相应用户的邮件存储空间中,如果用户要读取邮件,就需要通过邮件服务商的POP3邮件服务器来完成。最后,可能也有小伙伴们听说过IMAP协议,这个协议是对POP3协议的扩展,功能更强,作用类似,这里不再赘述.
发送qq邮件准备工作 。
首先我们需要先登录qq邮箱网页版,点击上方的设置按钮:
。
然后点击账户选项卡:
。
在账户选项卡中找到开启pop3/smtp选项,如下:
。
点击开启,开启相关功能,开启过程需要手机号码验证,按照步骤操作即可,不赘述。开启成功之后,即可获取一个授权码,将该号码保存好,一会使用.
然后我们需要javaxmail这个jar包,小伙伴可以直接去maven中央仓库下载,这里不再赘述.
发送 。
简单邮件 。
如果我们只发送一个简单的文本,发送方式就比较简单,整个过程可以分为三步如下:
第一步:构造smtp邮件服务器的基本环境 。
1
2
3
4
5
6
7
8
|
properties properties =
new
properties();
properties.setproperty(
"mail.host"
,
"smtp.qq.com"
);
properties.setproperty(
"mail.transport.protocol"
,
"smtp"
);
properties.setproperty(
"mail.smtp.auth"
,
"true"
);
properties.setproperty(
"mail.smtp.socketfactory.class"
,
"javax.net.ssl.sslsocketfactory"
);
properties.setproperty(
"mail.smtp.port"
,
"465"
);
session session = session.getdefaultinstance(properties);
session.setdebug(
true
);
|
第二步:构造邮件 。
1
2
3
4
5
6
|
mimemessage mimemessage =
new
mimemessage(session);
mimemessage.addrecipients(message.recipienttype.to,
"111@qq.com"
);
//设置收信人
mimemessage.addrecipients(message.recipienttype.cc,
"222@qq.com"
);
//抄送
mimemessage.setfrom(
"1510161612@qq.com"
);
//邮件发送人
mimemessage.setsubject(
"测试邮件主题"
);
//邮件主题
mimemessage.setcontent(
"hello,这是一封测试邮件"
,
"text/html;charset=utf-8"
);
//正文
|
第三步:发送邮件 。
1
2
3
4
|
transport transport = session.gettransport();
transport.connect(
"smtp.qq.com"
,
"333@qq.com"
,
"刚刚申请到的授权码"
);
transport.sendmessage(mimemessage, mimemessage.getallrecipients());
//发送邮件,第二个参数为收件人
transport.close();
|
复杂邮件 。
发送复杂邮件,第一步和第三步也是一样的,只有第二步构造邮件的过程比较麻烦,那么接下来给小伙伴们演示一个发送一封图文+两个附件的邮件。要发送复杂邮件,得先熟悉三个概念,如下:
1.mimemessage:该类是个能理解mime类型和头的电子邮件消息 。
2.mimemultipart:该类定义了增加、删除以及获取邮件不同部分内容的方法 。
3.mimebodypart:该对象代表一个mimemessage对象内容的一部分。每个mimebodypart被认为有两部分:mime类型和匹配这个类型的内容 。
完整的邮件生成过程如下(第一步和第三步参考上文):
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
|
mimemessage mimemessage =
new
mimemessage(session);
mimemessage.addrecipients(message.recipienttype.to,
"111@qq.com"
);
//设置收信人
mimemessage.addrecipients(message.recipienttype.cc,
"222@qq.com"
);
//抄送
mimemessage.setfrom(
"333@qq.com"
);
//邮件发送人
mimemessage.setsubject(
"测试邮件主题"
);
//邮件主题
mimemultipart mixed =
new
mimemultipart(
"mixed"
);
mimemessage.setcontent(mixed);
//设置整封邮件的mime消息体为混合的组合关系
mimebodypart attach1 =
new
mimebodypart();
//创建附件1
mimebodypart attach2 =
new
mimebodypart();
//创建附件2
mimebodypart content =
new
mimebodypart();
//创建邮件正文
mixed.addbodypart(attach1);
//将附件一添加到mime消息体中
mixed.addbodypart(attach2);
//将附件二添加到mime消息体中
mixed.addbodypart(content);
//将正文添加到消息体中
filedatasource fds1 =
new
filedatasource(
new
file(
"c:\\users\\sang\\desktop\\1.png"
));
//构造附件一的数据源
datahandler dh1 =
new
datahandler(fds1);
//数据处理
attach1.setdatahandler(dh1);
//设置附件一的数据源
attach1.setfilename(
"1.png"
);
//设置附件一的文件名
//附件二的操作与附件一类似,这里就不一一注释了
filedatasource fds2 =
new
filedatasource(
new
file(
"c:\\users\\sang\\desktop\\博客笔记.xlsx"
));
datahandler dh2 =
new
datahandler(fds2);
attach2.setdatahandler(dh2);
attach2.setfilename(mimeutility.encodetext(
"博客笔记.xlsx"
));
//设置文件名时,如果有中文,可以通过mimeutility类中的encodetext方法进行编码,避免乱码
mimemultipart bodymimemultipart =
new
mimemultipart(
"related"
);
//设置正文的mime类型
content.setcontent(bodymimemultipart);
//将bodymimemultipart添加到正文消息体中
mimebodypart bodypart =
new
mimebodypart();
//正文的html部分
bodypart.setcontent(
"<h1>hello大家好,这是一封测试邮件<img src='cid:2.png'/></h1>"
,
"text/html;charset=utf-8"
);
mimebodypart picpart =
new
mimebodypart();
//正文的图片部分
datahandler datahandler =
new
datahandler(
new
filedatasource(
"c:\\users\\sang\\desktop\\2.png"
));
picpart.setdatahandler(datahandler);
picpart.setcontentid(
"2.png"
);
//将正文的html和图片部分分别添加到bodymimemultipart中
bodymimemultipart.addbodypart(bodypart);
bodymimemultipart.addbodypart(picpart);
mimemessage.savechanges();
|
ok,java mail发送qq邮件就是这么简单,至于其他的如163,sina等,写法类似,这里我就不赘述了.
总结 。
以上所述是小编给大家介绍的springboot中发送qq邮件功能的实现代码,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对我网站的支持! 。
原文链接:https://segmentfault.com/a/1190000013092374 。
最后此篇关于SpringBoot中发送QQ邮件功能的实现代码的文章就讲到这里了,如果你想了解更多关于SpringBoot中发送QQ邮件功能的实现代码的内容请搜索CFSDN的文章或继续浏览相关文章,希望大家以后支持我的博客! 。
我需要将文本放在 中在一个 Div 中,在另一个 Div 中,在另一个 Div 中。所以这是它的样子: #document Change PIN
奇怪的事情发生了。 我有一个基本的 html 代码。 html,头部, body 。(因为我收到了一些反对票,这里是完整的代码) 这是我的CSS: html { backgroun
我正在尝试将 Assets 中的一组图像加载到 UICollectionview 中存在的 ImageView 中,但每当我运行应用程序时它都会显示错误。而且也没有显示图像。 我在ViewDidLoa
我需要根据带参数的 perl 脚本的输出更改一些环境变量。在 tcsh 中,我可以使用别名命令来评估 perl 脚本的输出。 tcsh: alias setsdk 'eval `/localhome/
我使用 Windows 身份验证创建了一个新的 Blazor(服务器端)应用程序,并使用 IIS Express 运行它。它将显示一条消息“Hello Domain\User!”来自右上方的以下 Ra
这是我的方法 void login(Event event);我想知道 Kotlin 中应该如何 最佳答案 在 Kotlin 中通配符运算符是 * 。它指示编译器它是未知的,但一旦知道,就不会有其他类
看下面的代码 for story in book if story.title.length < 140 - var story
我正在尝试用 C 语言学习字符串处理。我写了一个程序,它存储了一些音乐轨道,并帮助用户检查他/她想到的歌曲是否存在于存储的轨道中。这是通过要求用户输入一串字符来完成的。然后程序使用 strstr()
我正在学习 sscanf 并遇到如下格式字符串: sscanf("%[^:]:%[^*=]%*[*=]%n",a,b,&c); 我理解 %[^:] 部分意味着扫描直到遇到 ':' 并将其分配给 a。:
def char_check(x,y): if (str(x) in y or x.find(y) > -1) or (str(y) in x or y.find(x) > -1):
我有一种情况,我想将文本文件中的现有行包含到一个新 block 中。 line 1 line 2 line in block line 3 line 4 应该变成 line 1 line 2 line
我有一个新项目,我正在尝试设置 Django 调试工具栏。首先,我尝试了快速设置,它只涉及将 'debug_toolbar' 添加到我的已安装应用程序列表中。有了这个,当我转到我的根 URL 时,调试
在 Matlab 中,如果我有一个函数 f,例如签名是 f(a,b,c),我可以创建一个只有一个变量 b 的函数,它将使用固定的 a=a1 和 c=c1 调用 f: g = @(b) f(a1, b,
我不明白为什么 ForEach 中的元素之间有多余的垂直间距在 VStack 里面在 ScrollView 里面使用 GeometryReader 时渲染自定义水平分隔线。 Scrol
我想知道,是否有关于何时使用 session 和 cookie 的指南或最佳实践? 什么应该和什么不应该存储在其中?谢谢! 最佳答案 这些文档很好地了解了 session cookie 的安全问题以及
我在 scipy/numpy 中有一个 Nx3 矩阵,我想用它制作一个 3 维条形图,其中 X 轴和 Y 轴由矩阵的第一列和第二列的值、高度确定每个条形的 是矩阵中的第三列,条形的数量由 N 确定。
假设我用两种不同的方式初始化信号量 sem_init(&randomsem,0,1) sem_init(&randomsem,0,0) 现在, sem_wait(&randomsem) 在这两种情况下
我怀疑该值如何存储在“WORD”中,因为 PStr 包含实际输出。? 既然Pstr中存储的是小写到大写的字母,那么在printf中如何将其给出为“WORD”。有人可以吗?解释一下? #include
我有一个 3x3 数组: var my_array = [[0,1,2], [3,4,5], [6,7,8]]; 并想获得它的第一个 2
我意识到您可以使用如下方式轻松检查焦点: var hasFocus = true; $(window).blur(function(){ hasFocus = false; }); $(win
我是一名优秀的程序员,十分优秀!