Java发送邮件详解

article/2025/9/14 10:28:59

目录

一、关于电子邮件

电子邮件

传输协议

SMTP协议

POP3协议

邮件收发原理

二、发送纯文本邮件

二、发送带图片和附件的邮件


一、关于电子邮件

电子邮件

要在网络上实现邮件功能,必须要有专门的邮件服务器。

这些邮件服务器类似于现实生活中的邮局,它主要负责接收用户投递过来的邮件,并把邮件投递到邮件接收者的电子邮箱中。

SMTP服务器地址:一般是 smtp.xxx.com,比如163邮箱是smtp.163.com,qq邮箱是smtp.qq.com。

使用Java发送邮件,还需要设置使用账号开启相关服务,拿到授权码:

传输协议

SMTP协议

发送邮件:

我们通常把处理用户smtp请求(邮件发送请求)的服务器称之为SMTP服务器(邮件发送服务器)。

POP3协议

接收邮件:

我们通常把处理用户pop3请求(邮件接收请求)的服务器称之为POP3服务器(邮件接收服务器)。

邮件收发原理

1、首先通过smtp协议连接到Smtp服务器,然后发送一封邮件给网易的邮件服务器
2、网易分析发现需要去QQ的邮件服务器,通过smtp协议将邮件转投给QQ的Smtp服务器
3、QQ将接收到的邮件存储在545646733@qq.com这个邮件账号的空间中
4、再通过Pop3协议连接到Pop3服务器收取邮件
5、从545646733@qq.com这个邮件账号的空间中取出邮件
6、Pop3服务器将取出来的邮件送出去

二、发送纯文本邮件

使用Java发送邮件,首先需要引入相关的依赖:

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

JavaMail 是sun公司(现以被甲骨文收购)为方便Java开发人员在应用程序中实现邮件发送和接收功能而提供的一套标准开发包,它支持一些常用的邮件协议,如前面所讲的SMTP,POP3,IMAP,还有MIME等。我们在使用JavaMail API 编写邮件时,无须考虑邮件的底层实现细节,只要调用JavaMail 开发包中相应的API类就可以了。
Java发送邮件三步骤:

1、创建包含连接邮件服务器授权信息的Session对象

(1)编写抽象类Authenticator的实现子类,在子类中覆盖父类的getPasswordAuthentication方法,并返回封装用户名和密码的PasswordAuthentication对象;

(2) 调用Session.getInstance(Properties, Authenticator)方法获得Session类的实例对象,并把Authenticator对象注册到Session对象中。

2、创建代表邮件内容的Message对象

使用Session对象创建代表邮件消息内容的Message对象

3、通过Transport,发送Message

方式一:调用Transport.send静态方法发送Message对象中的邮件消息内容。send方法将从Message对象中获得Session对象的引用,然后将调用Session对象中注册的Authenticator对象从中获取认证信息后传递给邮件服务器。

方式二:使用Transport的connect方法连接邮件服务器,然后使用sendMessage发送发送邮件;最后调用close方法关闭邮件服务器的连接。(不推荐,麻烦)

代码示例:

public class SendEmail {public static void main(String[] args) throws MessagingException, GeneralSecurityException {Properties props = new Properties();// 设置邮件服务器 QQ:smtp.qq.com    163:smtp.163.comprops.setProperty("mail.smtp.host", "smtp.qq.com");// 设置是否需要验证用户名props.setProperty("mail.smtp.auth", "true");// 如果是QQ邮箱,还要设置SSL加密,加上以下代码即可MailSSLSocketFactory sf = new MailSSLSocketFactory();sf.setTrustAllHosts(true);props.put("mail.smtp.ssl.enable", "true");props.put("mail.smtp.ssl.socketFactory", sf);/*** 发送邮件三步骤*/// 1、创建定义整个应用程序所需的环境信息的Session 对象Session session = Session.getInstance(props, new Authenticator() {@Overrideprotected PasswordAuthentication getPasswordAuthentication() {// 发件人邮件用户名、授权码return new PasswordAuthentication("xxx@qq.com", "xxx");}});// 开启Session的debug模式,这样就可以查看到程序发送Email的运行状态session.setDebug(true);// 2、创建邮件对象MimeMessage message = new MimeMessage(session);// 发件人message.setFrom(new InternetAddress("xxx@qq.com"));// 指定收件人message.setRecipients(Message.RecipientType.TO, "xxx@126.com");// 指定抄送人message.setRecipients(Message.RecipientType.CC, "xxx@qq.com");// 设置邮件主题message.setSubject("Announcement");// 设置邮件内容message.setText("let's go party!");// 设置发送时间message.setSentDate(new Date());// 3、发送邮件,调用Transport.send静态方法发送Message对象中的邮件消息内容Transport.send(message);}
}

二、发送带图片和附件的邮件

先认识两个类一个名词:

MIME(多用途互联网邮件扩展类型)

MiniMultipart类

MiniMultipart类是一个容器类,包含MimeBodyPart类型的对象,Javamail邮件Multipart支持同时发text和html混合消息。

常见的multipart类型有三种:

multipart/mixed:附件。

multipart/related:内嵌资源。

multipart/alternative:纯文本与超文本共存。

如果在邮件中要添加附件,必须定义multipart/mixed段;如果存在内嵌资源,至少要定义multipart/related段;如果纯文本与超文本共存,至少要定义multipart/alternative段。什么是“至少”?举个例子说,如果只有纯文本与超文本正文,那么在邮件头中将类型扩大化,定义为multipart/related,甚至multipart/mixed,都是允许的。

MimeMultipart是Multipart的实现类,默认类别是mixed。其他multipart子类型如:related和alternative可以通过new MimeMultipart(“alternative”)来实现

代码示例:

public class SendEmail {public static void main(String[] args) throws MessagingException, GeneralSecurityException {Properties props = new Properties();// 设置邮件服务器 QQ:smtp.qq.com    163:smtp.163.comprops.setProperty("mail.smtp.host", "smtp.qq.com");// 设置是否需要验证用户名props.setProperty("mail.smtp.auth", "true");// 如果是QQ邮箱,还要设置SSL加密,加上以下代码即可MailSSLSocketFactory sf = new MailSSLSocketFactory();sf.setTrustAllHosts(true);props.put("mail.smtp.ssl.enable", "true");props.put("mail.smtp.ssl.socketFactory", sf);/*** 发送邮件三步骤*/// 1、创建定义整个应用程序所需的环境信息的Session 对象Session session = Session.getInstance(props, new Authenticator() {@Overrideprotected PasswordAuthentication getPasswordAuthentication() {// 发件人邮件用户名、授权码return new PasswordAuthentication("xxx@qq.com", "xxx");}});// 开启Session的debug模式,这样就可以查看到程序发送Email的运行状态session.setDebug(true);// 2、创建邮件对象MimeMessage message = new MimeMessage(session);// 发件人message.setFrom(new InternetAddress("xxx@qq.com"));// 指定收件人message.setRecipients(Message.RecipientType.TO, "xxx@126.com");// 指定抄送人message.setRecipients(Message.RecipientType.CC, "xxx@qq.com");// 设置邮件主题message.setSubject("带图片的信息");// 图片MimeBodyPart image = new MimeBodyPart();DataHandler dataHandler = new DataHandler(new FileDataSource("D:\\demofiles\\gougou.jpg"));image.setDataHandler(dataHandler);image.setContentID("gougou");// 图片设置ID// 文本MimeBodyPart text = new MimeBodyPart();text.setContent("这是一封邮件正文带图片<img src='cid:gougou' width='200' height='100'>的邮件", "text/html;charset=UTF-8");// 附件一MimeBodyPart appendix1 = new MimeBodyPart();// 把前一张图片覆盖掉了DataHandler appendixHandler1 = new DataHandler(new FileDataSource("D:\\demofiles\\lang.jpg"));appendix1.setDataHandler(appendixHandler1);appendix1.setFileName("lang.jpg");// 为附件设置名字,不能和内嵌文件重名,否则<img/>会解析出错// 附件二MimeBodyPart appendix2 = new MimeBodyPart();DataHandler appendixHandler2 = new DataHandler(new FileDataSource("D:\\demofiles\\flowers.jpg"));appendix2.setDataHandler(appendixHandler2);appendix2.setFileName("lang.jpg");// 附件和附件的名字可以一样,邮件会自动标号区别// 描述数据关系:文本+图片,捆绑成一个relatedMimeMultipart related = new MimeMultipart("related");related.addBodyPart(text);related.addBodyPart(image);// 将拼装好的正文内容捆绑成一个主体MimeBodyPart contentText =  new MimeBodyPart();contentText.setContent(related);// 描述数据关系: 附件+(文本+图片)MimeMultipart allFile =new MimeMultipart("mixed");allFile.addBodyPart(appendix1); // 附件一allFile.addBodyPart(appendix2); // 附件二allFile.addBodyPart(contentText);// 正文内容// allFile.addBodyPart(image); // 不能再设置image为附件,无效// allFile.addBodyPart(appendix2); // 附件同文件可以重复// 封装Message消息,保存修改message.setContent(allFile);message.saveChanges();// 设置发送时间message.setSentDate(new Date());// 3、发送邮件,调用Transport.send静态方法发送Message对象中的邮件消息内容Transport.send(message);}
}

代码中,<img/>标签用到了cid,那什么是cid呢?

一封邮件由邮件头(Headers)和邮件体组成的,邮件头中包括了各种属性,其中就有cid,即Content-Id,下图是Java邮件开发详解中对Content-id的解释(张孝祥版PDF)

这个cid跟这封邮件的内嵌资源一一对应,这个cid主要用来替换你下载到本地的资源文件比如gif表情,然后将src中的路径换成本地路径才能正常显示,这个没有附件容易理解,其实可以这样理解,他也是附件,就是你要先下载到本地,替换完之后才能正常的展示到用户面前,多了个下载的过程,而附件可以直接展示,点击某个附件再调用下载的过程。


http://chatgpt.dhexx.cn/article/Y6uSBXLM.shtml

相关文章

基于JavaMail的Java邮件发送:简单邮件发送

本文链接: https://blog.csdn.net/xietansheng/article/details/51673073 电子邮件的应用非常广泛&#xff0c;例如在某网站注册了一个账户&#xff0c;自动发送一封欢迎邮件&#xff0c;通过邮件找回密码&#xff0c;自动批量发送活动信息等。但这些应用不可能和我们自己平时…

js 实现计数器功能

1.运用 setInterval()定时器计算秒数 <!DOCTYPE html> <html><head><title>JS实现计数器</title><meta http-equiv"content-type" content"text/html; charsetgbk"><script src"https://cdn.bootcss.com/jqu…

element的formatter失效的解决方案

formatter传入数据失效 组件封装的时这样 使用方式还是和element的官方使用方式相同

html输入框只能输入文字,input文本框强制输入指定文字的方法以及IE11的兼容

背景:最近开发的韩国项目,在用户姓名输入框一栏中,要求只能输入韩文,通常用到onkeyup和onafterpaste两个事件来触发方法,并在方法中进行校验,但是在IE浏览器中,出现了一种情况,就是韩文单词拼写未完成的时候,会直接进行校验并显示,如下图实例所展示,并不是需要想要的…

jquery对表格行列的操作-jquery动态增加表格行或者列

jquery对表格的操作是老生常谈的问题。最近项目中用到了&#xff0c;今天在这里分享一下&#xff01; 效果大体如下&#xff1a; 分享一下代码吧&#xff01; html <div class"table-responsive" id"Bk_table" style"display:none;">&l…

动态改变Input和Textarea值Vue数据没有绑定的解决办法

背景&#xff1a; 我在循环里面的input框需要限制输入的值的类型&#xff0c;如果我绑定了change的方法的话 首先需要失去焦点才能生效&#xff0c;如果不失去焦点直接点击确定按钮是不能触发事件的 值还是原来的 &#xff0c;第二个如果层级多的话需要把索引什么的传过去用$se…

HTML 限制文本框只能输入数字 onkeyup+onafterpaste

限制文本框只能输入数字 < input onkeyup "if(isNaN(value))execCommand(undo)" onafterpaste "if(isNaN(value))execCommand(undo)" > < input name txt1 onchange "if(/\D/.test(this.value)){alert(只能输入数字);this.value;}" …

JAVAFX的table样式修改

直接上代码吧&#xff0c; .table-view{-fx-font-size: 16; 修改表格字体的大小 } 表头的背景设置 .table-view .column-header-background {-fx-background-color: #DBDBDB; } 表头设置 .table-view .column-header{-fx-border-color:#ffffff; -fx-border-width:0 1 …

bootstrap-table样式修改

bootstrap-table修改后的效果如下 1.删除边线 <style>.table>tbody>tr>td{border-top: 1px solid transparent !important;border-right: 1px solid transparent !important;border-left: 1px solid transparent !important;}.table>thead>tr>th{bord…

HTML常用table样式

转自&#xff1a;http://atgoingguoat.iteye.com/blog/2074431 常用table样式&#xff0c;备自己常年复制用。 效果图 Java代码 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.d…

一文图解自定义修改el-table样式

我们在使用element UI库的时候&#xff0c;确实给我们带来了许多便利&#xff0c;但是&#xff0c;往往组件库无法满足我们的业务需求&#xff0c;这时就需要我们在组件库的基础上修改样式。 今天水香木鱼一篇图解文章教大家如何在组件库的基础上去修改样式&#xff0c;今天我们…

el-table样式美化

<!-- 列表展示 --><el-table:data="tableData"v-loading="loading2"borderclass="mg-btm-20

ant design table样式修改合集

目录 1. 修改列头样式 改变列头文字颜色 改变列头背景颜色 2. 修改行样式 改变行文字颜色 隔行换色 3.列头居中&#xff0c;列居左/右 4.列表自动滚动 5. 列头超出省略并可以点击全显示 6.Table 点击某一行时改变选中行的边框颜色 7.Table 移入某一行时改变行的颜色 …

Element-UI:el-table样式修改

以下样式代码在less环境下生效&#xff0c;最终样式如下。 样式代码&#xff0c; /*修改table 表体的背景颜色和文字颜色*/ /deep/ .el-table {background-color: transparent;th,td {background-color: transparent;}.el-table__expanded-cell {background-color: transp…

ElementUI table 样式修改

一、概述 element-ui table 默认是白色背景&#xff0c;现在需要修改为黑色背景&#xff0c;白色文字。 二、代码实现 css样式 <style>/*修改table 的背景颜色和文字颜色*/.el-table td, .el-table th.is-leaf,.el-table--border, .el-table--group{border-color: black;…

table 样式美化

1. 单像素边框CSS表格 这是一个很常用的表格样式。 源代码: 1 <!-- CSS goes in the document HEAD or added to your external stylesheet -->2 <style type="text/css">3 table.gridtable {4 font-family: verdana,arial,sans-serif;5 font…

el-table 样式自定义

1.el-table 样式自定义 效果图: // tableRowClassName 通过值判断是否添加加class, // header-cell-style 头部样式 // row-style 行的样式 // cell-style 每个item 的样式 <el-table style"margin-bottom: 20px" :data"pmPopList" :row-class-name&q…

HTML table样式

如果想在网页中建一个如下table表格应该怎么做呢&#xff1f; 首先建一个表<table> <table>/*table标签就是建一个表格*/<tr>/*tr标签就是table row&#xff0c;即为表格中的一行*/<th>学号</th>/*th标签即table head&#xff0c;就是表头*/<…

Vue表格table样式

新入职的公司让我学习下Vue&#xff0c;以前没怎么学过&#xff0c;最近开始学习&#xff0c;记录下每天学习的内容&#xff0c;借鉴了很多前辈们的资料&#xff0c;如有冒犯&#xff0c;还请原谅。 开始我做的是动态表格&#xff0c;但是发现不会调整宽度&#xff0c;于是就改…

html中table美化,漂亮的css table样式

工作中发邮件通知人员样式总是一个麻烦事,工作的严肃性不能让邮件样式太花哨,但是又不能太简陋, 所以找了下面的table样式和大家分享。 效果如下图所示: 漂亮CSS Tables-幸凡学习网 body {font: normal 11px auto "Trebuchet MS", Verdana, Arial, Helvetica, sans-…