【我的Segmentfault原文】https://segmentfault.com/a/1190000008030346

前言

  JavaMail的使用本身并不难,网上有不少案例,简单易懂,而且有详细的中文注解。但是由于JavaMail的机制设置不够完善,特别是异常出错时的参考信息太少,给初学者造成了不少麻烦,而我就是其中之一。在此,把我遇到过得那些坑总结出来,以免大家重蹈覆辙,浪费时间。(注:后续还有遇到新的问题,我会持续更新到这里)

一、JavaMail概述

  JavaMail是由Sun定义的一套收发电子邮件的API,不同的厂商可以提供自己的实现类。但它并没有包含在JDK中,而是作为JavaEE的一部分。

  厂商所提供的JavaMail服务程序可以有选择地实现某些邮件协议,常见的邮件协议包括:

  • SMTP:简单邮件传输协议,用于发送电子邮件的传输协议;

  • POP3:用于接收电子邮件的标准协议;

  • IMAP:互联网消息协议,是POP3的替代协议。

  这三种协议都有对应SSL加密传输的协议,分别是SMTPS,POP3S和IMAPS。除JavaMail服务提供程序之外,JavaMail还需要JAF(JavaBeans Activation Framework)来处理不是纯文本的邮件内容,这包括MIME(多用途互联网邮件扩展)、URL页面和文件附件等内容。下图描述了JavaMail的体系结构。

(图片来源:http://blog.csdn.net/t12x3456...

  • mail.jar:此JAR文件包含JavaMail API和Sun提供的SMTP、IMAP和POP3服务提供程序;

  • activation.jar:此JAR文件包含JAF API和Sun的实现。

(有关JavaMail的介绍我只摘要部分,详细介绍请参考:http://blog.csdn.net/zapldy/a...

二、各种问题及分析说明

  后面列举出来的报错信息需要开启Session的debug模式,具体配置方式如下:

Session sendMailSession = Session.getInstance(pro, authenticator);
sendMailSession.setDebug(true);

1、后台显示邮件发送成功但未收到邮件

问题现象

  使用新浪邮箱发送邮件,尝试两种邮件发送方式,分别是“A@sina .cn发送给A@sina .cn”和“A@sina .cn发送给B@sina .cn”,摘要部分后台打印信息:

250 ok queue id 355937395546
QUIT
221 smtp-5-121.smtpsmail.fmail.xd.sinanode.com
Sent message ***@sina.cn successfully....

  使用163邮箱发送邮件,尝试C@126.com发送给A@sina .cn,摘要部分后台打印信息:

250 Mail OK queued as smtp7,C8CowADnDNooqmNYHWsYGw--.30359S3 1482926655
QUIT
221 Bye
Sent message ***@sina.cn successfully....

  登录新浪邮箱确认有smtp服务且处于开通状态,也尝试重新开启smtp服务,仍然邮件发送不成功。网上也有不少人反馈用手机客户端无法使用新浪邮箱发送邮件,随后我尝试用foxmail登录新浪邮箱,也出现只能接收邮件而不能发送邮件的情况。

问题分析

  基本确定是新浪邮箱问题,至于是smtp服务问题,还是做什么限制就不清楚了。好像平时也没多少人用新浪邮箱发邮件,通过网页登录也是能发邮件的,凑合能用,毕竟是免费邮箱嘛。

  这是用JavaMail发送邮件遭遇的第一个问题,案例都是参考别人原封不动拿过来用的,却发了收不到邮件。换了几个参考案例,问题现象相同。我开始怀疑别人给的案例代码问题,毕竟堂堂的新浪邮箱还不至于这么不靠谱。然后,就是基于这样的判断,我就吃了大亏,一直在分析代码和配置方式,也在各大论坛搜“发送邮件成功却收不到邮件”,发现出现问题的不在少数,而且多半给出的建议是检查代码有没有问题,然后提问的人也没了回复下文,这就导致了很大的误导性。这正是因为这个原因,我也白白地耗了好几天时间,直到最后发现原来原因是这么简单...有时别人的解答能够事半功倍,但是这种依赖性还是不靠谱的,有时自己的排错思路更重要

2、向新浪邮箱发信被退信

问题现象

  平时开发测试,不想用私人常用邮箱,于是注册了搜狐邮箱,并尝试向新浪邮箱发送邮件,不过很快搜狐邮箱收到退信(这种情况JavaMail是不会提示判断信息的),退信内容如下:

<A@sina .cn>: host freemx1.sinamail.sina.com.cn[202.108.35.47] said:
554 Rejected due to the sending MTA's poor reputation. Please refer
http://mail.sina.com.cn/help2... Please refer to
http://chengxin.mail.sina.com... 123.125.123.1
(in reply to DATA command)

问题分析

  通过访问退信信息里面的链接(新浪邮箱诚信平台),基本确定搜狐邮箱服务器被拉黑了。当然,不是被新浪拉黑,而是进了RBL黑名单,新浪参考其数据进行了屏蔽。这个已经超出了个人能力范围,果断放弃新浪邮箱,改向其他邮箱发送。

【RBL黑名单】

RBL是英文Realtime BlackholeList的缩写,即实时黑名单列表。在该列表中的IP地址对外发布过垃圾邮件。是由第三方的反垃圾邮件组织提供的检查垃圾邮件发送者地址的服务。

【查询网站】

MXToolBox:http://mxtoolbox.com/ 
BlackListAlert:http://www.blacklistalert.org/

3、向163邮箱发信未收到且也无未退信

问题现象

  通过搜狐邮箱向新浪邮箱发信遭遇退信后,我尝试自己发给自己,正常收到邮件。考虑模拟测试要尽量真实,我改向163邮箱发信,结果出现后台显示发信成功,163邮箱却没收到邮件,但本地邮箱并没收到退信通知。

问题分析

  这说明“后台显示邮件发送成功但未收到邮件”的情况,原因还是多种多样的,不仅可能发件服务器有问题,还可能是收件服务器的问题。收件服务器有的给你退信,有的还收了直接丢弃,真是什么奇葩情况都有,多加注意吧。

4、jar包重叠存在javax.mail.*

问题现象

  从Oracle官网下载下来JavaMail相关jar包是mail.jar,导入进去测试后报各种奇葩错误。下面的异常信息是在项目中已有geronimo-javamail_1.4_spec-1.3.jar的情况下导入mail.jar后报出来的:

com.sun.mail.smtp.SMTPSendFailedException: 530 Authentication required
 at com.sun.mail.smtp.SMTPTransport.issueSendCommand(SMTPTransport.java:1388)
 at com.sun.mail.smtp.SMTPTransport.mailFrom(SMTPTransport.java:959)
 at com.sun.mail.smtp.SMTPTransport.sendMessage(SMTPTransport.java:583)

  不仔细看还以为是账号或密码填错了,其实只要把geronimo-javamail_1.4_spec-1.3.jar剔除,重新发邮件就正常了。

问题分析

  上面只是我贴出来的报错情况之一,这些报错是不一定能够复现,因为导包就存在问题,重叠存在javax.mail.*。我是在出现第一个问题(“后台显示邮件发送成功但未收到邮件”)的时候,在网上看到别人说的这种情况(javaMail发送邮件成功却收不到邮件或收到邮件无主题无收件人乱码),而后我就开始逐个排查定位,目前通过我所知道的情况来看,重叠存在javax.mail.*的jar有mail.jar、geronimo-javamail_1.4_spec-1.x.jar、mailapi.jar和javaee.jar。
  排查的方法也很简单,比如打开javax.mail.Session,然后定位它所在的jar,剔除后再找下一个jar包。

5、jar包正确的情况下也出现报错

问题现象

  在jar包正常且配置正确的情况下,我也遇到过不少报错情况。出现的情况基本是前几次发邮件都正常,然后再发一次又突然出现报错,再试一次问题又不复现,贴出几种报错信息如下:

(报错1)

DEBUG SMTP: Sending failed because of invalid destination addresses
RSET
DEBUG SMTP: MessagingException while sending, THROW:
javax.mail.SendFailedException: Invalid Addresses;
  nested exception is:
    com.sun.mail.smtp.SMTPAddressFailedException: 554 5.7.1 <*@163.com>: Relay access denied
    at com.sun.mail.smtp.SMTPTransport.rcptTo(SMTPTransport.java:1862)
    at com.sun.mail.smtp.SMTPTransport.sendMessage(SMTPTransport.java:1118)

(报错2)

Exception in thread "main" java.lang.RuntimeException: javax.mail.MessagingException: Could not convert socket to TLS;
  nested exception is:
    javax.net.ssl.SSLHandshakeException: sun.security.validator.ValidatorException: PKIX path validation failed: java.security.cert.CertPathValidatorException: timestamp check failed

(报错3)

javax.mail.SendFailedException: Send failure (javax.mail.MessagingException: Could not connect to SMTP host: smtp.sohu.com, port: 25 (java.net.ConnectException: Connection timed out: connect))
    at javax.mail.Transport.send(Transport.java:163)
    at javax.mail.Transport.send(Transport.java:48)
    at javamail.EmailSender.sendMail(EmailSender.java:91)
    at javamail.EmailSender.main(EmailSender.java:64)

(报错4)

250-zw_71_47
250-AUTH PLAIN LOGIN
250 STARTTLS
DEBUG SMTP: Found extension "AUTH", arg "PLAIN LOGIN"
DEBUG SMTP: Found extension "STARTTLS", arg ""
DEBUG SMTP: Attempt to authenticate using mechanisms: LOGIN PLAIN DIGEST-MD5 NTLM
DEBUG SMTP: AUTH LOGIN command trace suppressed

问题分析

  因为这些报错不具有可复现性,测试过程中我也司空见惯,当然90%以上的情况邮件发送都是正常,代码方面也是综合了多个案例提炼出来的,而且代码大同小异,也看过官方提供的样例,配置内容都差不多,代码问题可能性较小,也不排除smtp服务器抽风了,目前我暂时忽略。   当然,如果有分析出是代码问题,也欢迎留言告知分享。(注:后面文章我会将我的代码粘贴出来共享)

6、发信成功后,回应的信息不同

问题现象

  我将JavaMail代码在外网测试邮件发送成功时,后台打印信息结尾内容基本如下:

250 Mail OK queued as smtp7,C8CowADnDNooqmNYHWsYGw--.30359S3 1482926655
QUIT
221 Bye

  当我将JavaMail代码移植到内部环境测试邮件发送成功时,后台打印信息结尾内容如下:

250 Message accepted for delivery
QUIT
221 srv201.mail.*.* SMTP Service closing transmission channel

问题分析

  通过上网查询资料得知,250和221这样的编码实际是smtp交互的消息编码,其中221代表邮件会话即将结束,这意味着所有消息都已被处理。编码后面的信息“srv201.mail.. SMTP Service closing transmission channel”和“Bye”的意思类似,可以忽略具体内容,知道221代表邮件发送正常即可。

221 The server is closing its transmission channel. It can come with side messages like "Goodbye" or "Closing connection". The mailing session is going to end, which simply means that all messages have been processed.

三、附录

1、SMTP错误码及建议解决方法
2、SMTP errors and reply codes
3、javaMail发送邮件成功却收不到邮件或收到邮件无主题无收件人乱码
4、新浪邮箱诚信平台

JavaMail邮件发送不成功的那些坑人情况及分析说明的更多相关文章

  1. javamail邮件发送例子

    public class EmailTask{        // Session used by the javamail classes    private Session session;   ...

  2. Spring的javaMail邮件发送(带附件)

    项目中经常用到邮件功能,在这里简单的做一下笔记,方便日后温习. 首先需要在配置文件jdbc.properties添加: #------------ Mail ------------ mail.smt ...

  3. javaMail 邮件发送和接收示例,支持正文图片、html、附件(转)

    转自:https://blog.csdn.net/star_fly4/article/details/52037587 一.RFC882文档简单说明 RFC882文档规定了如何编写一封简单的邮件(纯文 ...

  4. JavaMail 邮件发送

    jar包部署 /** * 通过SMTP进行邮件集成 */ public class CmpSendMail { // 邮件发送服务器主机 private final static String HOS ...

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

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

  6. 应用层之E-mail服务及javaMail邮件发送的知识总结

    关于Email服务你需要知道的知识点: 概述: 今天来介绍一下应用层的电子邮件服务,我们每天几乎都在用,电子邮件(email)服务也是一种基于C/S模式的服务,它采用的是一种"存储-转发&q ...

  7. javaMail邮件发送的简单实现

    package com.test.mail; import java.util.Properties; import javax.mail.Message; import javax.mail.Ses ...

  8. javaMail邮件发送功能(多收件人,多抄送人,多密送人,多附件)

    private Session session; private Transport transport; private String mailHost = ""; privat ...

  9. (转)JavaMail邮件发送-发送一个文本邮件和一些问题说明

    需要下载的JAR包: JavaMail:http://www.oracle.com/technetwork/java/javamail/index.html JAF:http://www.oracle ...

随机推荐

  1. Nagios 系统监控基本安装配置过程详解

    Nagios 是一款免费的开源 IT 基础设施监控系统,功能强大,灵活性强,能有效监控 Windows.Linux.VMware 和 Unix 主机状态,交换机.路由器等网络设置等.一旦主机或服务状态 ...

  2. 【转】OSX键盘快捷键

    OS X 键盘快捷键 了解有关常见 OS X 键盘快捷键的信息.键盘快捷键是通过按下键盘上的组合键来调用 OS X 功能的一种方式. 若要使用键盘快捷键或按键组合,您可以同时按修饰键和字符键.例如,同 ...

  3. HDU5832

    A water problem Time Limit: 5000/2500 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others)T ...

  4. [TPYBoard-Micropython之会python就能做硬件 2] 利用micropython控制NOKIA 5110屏

    转载请注明:@小五义 http://www.cnblogs.com/xiaowuyi 欢迎加入讨论群 64770604 一.本次实验所需器材 1.TPYboard V102板  一块 2.DS3231 ...

  5. 只为粗暴看一下ES6的字符串模板的性能

    网上查找"ES6 字符串模板 +性能"5分钟无果遂写了一个暴力测试. 测试对象: +=方式,字符串累加计算方式 +s1+s2...+sn方式,即传统连加拼接字符串方式 s.push ...

  6. “-webkit-font-smoothing”

    CSS3里面加入了一个"-webkit-font-smoothing"属性. 这个属性可以使页面上的字体抗锯齿,使用后字体看起来会更清晰舒服. 加上之后就顿时感觉页面小清晰了. 淘 ...

  7. 重写titleView

    在一些特定的情况下不能使用原有的titleView需要重写titleView代码如下 #import "TitleView.h" @implementation TitleView ...

  8. .NET十五周年生日快乐 (3月7日发布Visual Studio 2017正式版?)

    今天 是.NET 对世界首次亮相15 周年.2002 年 2 月 13 日,第一版本的.NET 发布作为 Visual Studio.NET 的一部分.它仿佛就在昨天为微软建设成"下一代 W ...

  9. 游戏UI框架设计(二) : 最简版本设计

    游戏UI框架设计(二) --最简版本设计 为降低难度决定先讲解一个最简版本,阐述UI框架的核心设计理念.这里先定义三个核心功能: 1:UI窗体的自动加载功能. 2:缓存UI窗体. 3:窗体生命周期(状 ...

  10. 解析jQuery中extend方法--源码解析以及递归的过程《二》

    源码解析 在解析代码之前,首先要了解extend函数要解决什么问题,以及传入不同的参数,会达到怎样的效果.extend函数内部处理传入的不同参数,返回处理后的对象. extend函数用来扩展对象,增加 ...