使用过JavaMail的api发送邮件的人可能会有这样一个疑惑:我如何知道我调用该api发送的邮件是否成功呢?一般的开放的api给我们调用都会有个返回值或者状态码,来告诉我们执行成功与否。但是JavaMail却没有提供这样一个返回值。

所以在调用JavaMail发送邮件的时候,我们只能通过catch异常的方式来判断邮件是否发送成功。我们认为只要没有异常发生,那么邮件就能发送成功。那么我们就来分析一下JavaMail为什么没有提供返回值,和通过异常判断邮件发送成功状态是否靠谱。

JavaMail发送邮件原理

在使用JavaMail进行发送邮件时,我们必须提供一个邮件会话。创建邮件会话的过程如下:

Properties props = new Properties();
        // 发送邮件的服务器的IP和端口
        props.put("mail.smtp.host", MAIL_SMTP_HOST);
        props.put("mail.smtp.port", MAIL_SMTP_PORT);
        // 是否需要身份验证
        props.put("mail.smtp.auth", "true");

        props.put("mail.smtp.socketFactory.class", "javax.net.ssl.SSLSocketFactory");
        Session session = Session.getDefaultInstance(props, new Authenticator() {
            protected PasswordAuthentication getPasswordAuthentication() {
            // 登陆邮件发送服务器的用户名和密码
                return new PasswordAuthentication(MAIL_SENDER_MAIL, MAIL_SENDER_PASS);
            }
        });

  分析一下代码。在创建Session之前我们先创建一个Properties,这个Properties设置了这样几个参数:mail.smtp.hostmail.smtp.portmail.smtp.authmail.smtp.socketFactory.class。在创建Session的时候还要传入发送邮件使用的用户名及密码。

发送邮件代码如下:

//使用JavaMail发送邮件的5个步骤
        //1、创建session
         Session session = Session.getInstance(prop);
         //开启Session的debug模式,这样就可以查看到程序发送Email的运行状态
         session.setDebug(true);
         //2、通过session得到transport对象
         Transport ts = session.getTransport();
         //3、使用邮箱的用户名和密码连上邮件服务器,发送邮件时,发件人需要提交邮箱的用户名和密码给smtp服务器,用户名和密码都通过验证之后才能够正常发送邮件给收件人。
         ts.connect("smtp.sohu.com", "gacl", "邮箱密码");
         //4、创建邮件
         Message message = createSimpleMail(session);
         //5、发送邮件
         ts.sendMessage(message, message.getAllRecipients());
         //关闭连接
         ts.close();

总结发送邮件过程主要有以下几个步骤:

1.创建包含邮件服务器的网络链接的Session对象
2.创建代表邮件内容的Message对象
3.创建Transport对象
4.链接服务器
5.发送Message
6.关闭链接

由于Transport只是一个抽象类,所以这里在发送Message的时候用调用的方法ts.sendMessage实际上是调用的Transport的实现类SMTPTransportsendMessage方法。
SMTPTransportsendMessage方法则依赖SMTP协议进行邮件的发送。

所以,当javamail使用smtp服务发送邮件时,当你把邮件发送到smtp服务器的时候,你只能得到已经发送到smtp的队列中的状态,但是邮件服务器是否能发送成功,你是得不到的。就是说,你不能保证邮件发送一定成功。 这就取决于SMTP协议的内容传输了。

但是SMTP协议如果传输失败,是会报错的。SMTP由TCP提供的可靠的数据传输服务把邮件消息从发信人的邮件服务器传送到收信人的邮件服务器。
所以我们可以认为当我们调用JavaMail发送邮件时,如果程序没有报错则表示邮件发送成功。

SMTP工作机制

SMTP通常有两种工作模式:发送SMTP和接收SMTP。
具体工作方式为:发送SMTP在接到用户的邮件请求后,判断此邮件是否为本地邮件,若是直接投送到用户的邮箱,否则向dns查询远端邮件服务器的MX纪录,并建立与远端接收SMTP之间的一个双向传送通道,此后SMTP命令由发送SMTP发出,由接收SMTP接收,而应答则反方面传送。一旦传送通道建立,SMTP发送者发送MAIL命令指明邮件发送者。如果SMTP接收者可以接收邮件则返回OK应答。SMTP发送者再发出RCPT命令确认邮件是否接收到。如果SMTP接收者接收,则返回OK应答;如果不能接收到,则发出拒绝接收应答(但不中止整个邮件操作),双方将如此重复多次。当接收者收到全部邮件后会接收到特别的序列,如果接收者成功处理了邮件,则返回OK应答即可。

SMTP工作过程

简单邮件传输协议(SMTP)是一种基于文本的电子邮件传输协议,是在因特网中用于在邮件服务器之间交换邮件的协议。SMTP是应用层的服务,可以适应于各种网络系统。
SMTP的命令和响应都是基于文本,以命令行为单位,换行符为CR/LF。响应信息一般只有一行,由一个3位数的代码开始,后面可附上很简短的文字说明。
SMTP要经过建立连接、传送邮件和释放连接3个阶段。具体为:

(1)建立TCP连接。
(2)客户端向服务器发送HELO命令以标识发件人自己的身份,然后客户端发送MAIL命令。
(3)服务器端以OK作为响应,表示准备接收。
(4)客户端发送RCPT命令。
(5)服务器端表示是否愿意为收件人接收邮件。
(6)协商结束,发送邮件,用命令DATA发送输入内容。
(7)结束此次发送,用QUIT命令退出。

SMTP服务器基于DNS中的邮件交换(MX)记录路由电子邮件。电子邮件系统发邮件时是根据收信人的地址后缀来定位邮件服务器的。SMTP通过用户代理程序(UA)完成邮件的编辑、收取和阅读等功能;通过邮件传输代理程序(MTA)将邮件传送到目的地。

JavaMail如何保证邮件发送成功的更多相关文章

  1. ActiveMQ入门系列之应用:Springboot+ActiveMQ+JavaMail实现异步邮件发送

    现在邮件发送功能已经是几乎每个系统或网址必备的功能了,从用户注册的确认到找回密码再到消息提醒,这些功能普遍的会用到邮件发送功能.我们都买过火车票,买完后会有邮件提醒,有时候邮件并不是买完票立马就能收到 ...

  2. 使用javaMail实现简单邮件发送

    一.首先你要用来发送邮件的qq邮箱需要开通pop3/smtp服务,这个可以百度一下就知道了 二.导入所需要的jar包,我使用的是maven添加依赖 <dependency> <gro ...

  3. java-基于JavaMail的Java邮件发送

    1.基于JavaMail的Java邮件发送:简单邮件发送 2.基于JavaMail的Java邮件发送:复杂邮件发送

  4. 基于JavaMail的Java邮件发送:复杂邮件发送

    参考:http://blog.csdn.net/xietansheng/article/details/51722660package com.bfd.ftp.utils;import java.ut ...

  5. 【转】基于JavaMail的Java邮件发送

    http://blog.csdn.net/xietansheng/article/details/51673073 http://blog.csdn.net/xietansheng/article/d ...

  6. jenkins构建邮件自动发送,测试邮件发送成功,构建项目邮件发送不成功的问题

    提示问题: Connection error sending email,retrying once more in 10 seconds…… Connection error sending ema ...

  7. JavaMail技术实现邮件发送转【】

    1.导入2个jar包,mail.jar,activation.jar 2.导入的jar包与myeclipse中自带的javaee 中的javaee.jar中的javax.activation包及jav ...

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

    使用Java应用程序发送 E-mail 十分简单,但是首先你应该在你的机器上安装 JavaMail API 和Java Activation Framework (JAF) . 您可以从 Java 网 ...

  9. 在outlook中发邮件判断邮件发送成功的方法

    早上给企业发了求职邮件,但是发送的时候,自己发现附件比较大,因为之前比较少使用这个工具来发邮件,所以发送之后没有提醒成功与否,求职心切,内心变得比较紧张. 所以查了查方法,发现了以下解决方案,现备注下 ...

随机推荐

  1. SQL Server 2012 BI 学习 第一天

    了解数据源,数据源视图,多维数据集,维度 数据源:一个数据库或者其它数据链接,SSAS不支持使用模拟功能来处理 OLAP 对象.模拟信息选择“使用服务帐户” 数据源视图:DSV是元数据的单个统一视图, ...

  2. Python-Day4 Python基础进阶之生成器/迭代器/装饰器/Json & pickle 数据序列化

    一.生成器 通过列表生成式,我们可以直接创建一个列表.但是,受到内存限制,列表容量肯定是有限的.而且,创建一个包含100万个元素的列表,不仅占用很大的存储空间,如果我们仅仅需要访问前面几个元素,那后面 ...

  3. 【笔记】WPF之模板控件应用

    最近在捣鼓WPF的动画,想自定义一个控件模型来实现动画. 目标功能是这样:在WPF项目文件中创建一个自定义用户控件模型,该模型最外层是一个Grid,Grid布局为3行1列,第一列是一个图片按钮,第二列 ...

  4. 新手自学ABAP(1)--数据类型

    一.DATA语句 1.TYPE type ex:  可以利用冒号声明多个变量. DATA : gv_num1 TYPE I,   gv_num2 TYPE I. 2.LIKE num   (num可以 ...

  5. 记一次Surface Pro 2还原操作

    因为要做Azure的一个case,对自己的域环境下直接进行了捕获.结果导致机器直接crash. 重启后使用本地账号登陆后发现所有Win 8 的App都无法使用,包括进入设置中还原方式也无法使用. 可以 ...

  6. 世界级Oracle专家Jonathan Lewis:我很为DBA们的未来担心(图灵访谈)

    部分节选 图灵社区:如果您的子女对计算机科学感兴趣,你会让他们选什么具体的方向呢? JL:我的孩子对计算机科学一点都不感兴趣,甚至对科学都没什么兴趣.他们主修的都是艺术.如果要我给其他的人建议的话,我 ...

  7. SetTimeOut jquery的作用

    1. SetTimeOut() 1.1 SetTimeOut()语法例子 1.2 用SetTimeOut()执行Function 1.3 SetTimeOut()语法例子 1.4 设定条件使SetTi ...

  8. raiserror的用法

    描述:raiserror :是用于抛出一个错误 第一个参数:{ msg_id | msg_str | @local_variable } msg_id:表示可以是一个sys.messages表中定义的 ...

  9. Java的哪些事

    Java的哪些事--------------------------------------------------Java学习分2个方面: Java语法与Java类库 Java: A simple, ...

  10. C#更改控制台文本颜色

    C#更改控制台文本的前景色和背景色   关键字:C# NET 控制台 前景色 背景色地址:http://www.cnblogs.com/txw1958/archive/2012/12/07/cshar ...