java使用smtp协议发送邮件注意的问题

公司经常遇到发送邮件的问题,普通邮件发送就不说了,说一下无账号密码发送邮件的过程,在这里总结一下:

邮件收发协议:发送邮件使用smtp协议,收取邮件使用pop或imap协议;这里我们只讲发送邮件的smtp协议;

smtp发送邮件过程

这部分说明是从网上摘抄的,写的很详细,我就贴过来修改了一下:

使用smtp协议发送邮件给邮件服务器时规定了要做以下几件事:

  1、使用"ehlo"命令和连接上的smtp服务器打声招呼,例如:
     ehlo zqz
               命令格式为  “ehlo 当前计算机的hostname”; zqz即为当前计算机的主机名;

  2、使用"auth login"命令登录到Smtp服务器,登录使用的用户名和密码必须经过Base64加密,例如:
    ①、输入命令:auth login  
    ②、输入使用Base64加密过后的用户名:Z2FjbA==
    ③、输入Base64加密过后的密码:MTIzNDU2
            说明:好多企业内部邮箱不需要设置用户名密码,一般都是将发送邮件的服务器ip列入白名单,那么这一步就可以省略;

  3、指明邮件的发件人和收件人

    mail from:<gacl@sohu.com>
    rcpt to:<xdp_gacl@sina.cn>

   4、编写要发送的邮件内容,邮件的编写格式是有一定的规则的,一封格式良好的邮件应该包含邮件头和邮件的主体内容。

 邮件头使用下面的三个字段来指明:

  1. from字段用于指明邮件的发送人
  2. to字段用于指明邮件的收件人
  3. subject字段用于指明邮件的主题

   邮件的内容包含了这些信息之后才是一封格式良好的邮件。

    ①、输入"data"命令
      data
    ②、编写邮件内容
                    Cc:zhuqz@tingyun.com                    ----邮件头   抄送给谁
      From:etptest@tingyun.com              ----邮件头   邮件发送者
      To:79457965@qq.com            ----邮件头   邮件接收者
      Subject:hello test         ----邮件头   邮件标题
                          ----空行
      hello test                 ----邮件的具体内容

  5、输入一个.告诉邮件服务器邮件内容已经写完了。
    .
  6、输入quit命令断开与邮件服务器的连接。
    quit
 

以上的6个步骤就是Smtp协议规定的发送一封Email必须要做的事情。

 

下面就用命令行来执行一下整个过程:

[C:\Users\Administrator]$ telnet smtp.tingyun.com 25

Host 'smtp.tingyun.com' resolved to 163.177.72.143.
Connecting to 163.177.72.143:25...
Connection established.
To escape to local shell, press 'Ctrl+Alt+]'.

220 smtp.qq.com Esmtp QQ Mail Server         //连接成功后服务器主动推送的消息,220为响应代码,后面欢迎消息说明服务器的域名为smtp.qq.com ,协议为Esmtp ,服务器名为QQ Mail Server;

ehlo localhost                                         //此命令成功后,服务器推送支持的认证方式
250-smtp.qq.com
250-PIPELINING
250-SIZE 73400320
250-STARTTLS
250-AUTH LOGIN PLAIN                       //这里是服务器返回的支持的验证方式 LOGIN 和PLAIN两种方式
250-AUTH=LOGIN
250-MAILCOMPRESS
250 8BITMIME
auth login                                             //此命令向服务器发起认证请求
334 VXNlcm5hbWU6                           //334代表等待输入命令  后面字符串代表输入用户名 ,解码后就是Username:
ZXRwdGVzdEB0aW5neXVuLmNvbQ==           //base64的用户名    
334 UGFzc3dvcmQ6                            //334代表等待输入命令  后面字符串代表输入密码,解码之后就是Password:
VFl1bjAxMA==                                                 //base64的密码
235 Authentication successful            //235代表验证通过,如果验证失败则返回530
mail from:<etptest@tingyun.com>   //谁发送的邮件
250 Ok
rcpt to:<79457965@qq.com>           //谁接收邮件
250 Ok
data                                                   //data命令代表邮件正文
354 End data with <CR><LF>.<CR><LF>       //354代表可以发送邮件正文,并提示邮件以"."结尾

 

From:etptest@tingyun.com             //发送者
To:79457965@qq.com                     //接收者
Cc:zhuqz@tingyun.com                    //抄送
Subject:hello test                               //标题
Content-Type: text/plain

                                                           //回车空行 ,此行上面是head,下面是body
hello test.                                           //邮件正文
.                                                          //  .代表正文结束
250 Ok: queued as 

 

 

以上红色部分为我们自己需要输入的命令行。

 

qq邮箱收到的邮件:

 

hello test

 

发件人:etptest <etptest@tingyun.com>     
时   间:2018年5月9日(星期三) 下午5:36纯文本 | 

收件人:

randolpha <79457965@qq.com>

抄   送:

zhuqz <zhuqz@tingyun.com>

 
 

hello test.

SMTP协议中HELO和EHLO

 


HELO是普通SMTP,不带身份验证,可以伪造邮件!一般如果不关闭SMTP的话,就可以制造垃圾邮件了,这个已经没有公司使这种方式了;

EHLO是ESMTP,带有身份验证,所以没法伪造。

 

 

 

java中SMTP协议发送邮件

 


SMTP协议发送邮件使用的是com.sun.mail.smtp.SMTPTransport这个类,建立连接,验证身份的逻辑在protocolConnect方法里面;
如果不设置mail.smtp.auth 和 mail.smtp.ehlo ,默认mail.smtp.auth = false,mail.smtp.ehlo=true;
相关的代码逻辑在com.sun.mail.smtp.SMTPTransport.protocolConnect()的613行:

 

 

 

       // setting mail.smtp.ehlo to false disables attempts to use EHLO
	boolean useEhlo =  PropUtil.getBooleanSessionProperty(session, "mail." + name + ".ehlo", true);
	// setting mail.smtp.auth to true enables attempts to use AUTH
	boolean useAuth = PropUtil.getBooleanSessionProperty(session, "mail." + name + ".auth", false);

判断是否需要执行auth login操作验证用户名和密码在第682行:
 

if ((useAuth || (user != null && passwd != null)) &&
		  (supportsExtension("AUTH") ||
		   supportsExtension("AUTH=LOGIN"))) {
		connected = authenticate(user, passwd);

注意这里的判断条件 ,如果mail.smtp.auth = true 或者 用户名和密码都不为null;
也就是在以下条件都会进程login验证:
1. mail.smtp.auth = true ;
2. mail.smtp.auth = false, 但是用户名和密码都不为null;

所以如果我们不去设置mail.smtp.auth参数(那么它默认就是false),只要将用户名和密码设置为null或者非null,即可让java决定是否需要执行login操作;所以建议不要设置mail.smtp.auth参数,只使用用户名和密码来控制是否执行login操作;

注意:
1. 对于不需要用户名和密码发送邮件的情况,需要将mail.smtp.auth = false或不设置(默认就是fasle),并把userName和password设置为null;

2. 对于exchange邮箱发送邮件,userName不要设置加@邮箱域名后面的内容,只需要@符号前的用户名即可;

状态码查询

500 格式错误,命令不可识别(此错误也包括命令行过长)
501 参数格式错误
502 命令不可实现
503 错误的命令序列
504 命令参数不可实现
211 系统状态或系统帮助响应
214 帮助信息
220 <domain> 服务就绪
221 <domain> 服务关闭传输信道
421 <domain> 服务未就绪,关闭传输信道(当必须关闭时,此应答可以作为对任何命令的响应)
250 要求的邮件操作完成
251 用户非本地,将转发向<forward-path>
450 要求的邮件操作未完成,邮箱不可用(例如,邮箱忙)
550 要求的邮件操作未完成,邮箱不可用(例如,邮箱未找到,或不可访问)
451 放弃要求的操作;处理过程中出错
551 用户非本地,请尝试<forward-path>
452 系统存储不足,要求的操作未执行
552 过量的存储分配,要求的操作未执行
553 邮箱名不可用,要求的操作未执行(例如邮箱格式错误)
354 开始邮件输入,以<CRLF>.<CRLF>结束
554 操作失败

 

如果要使用SSL发送邮件:

 

mail.smtp.starttls.enable=true; mail.smtp.ssl.protocols=TLSv1.2;

mail.smtp.starttls.enable的说明:

If true, enables the use of the STARTTLS command (if supported by the server) to switch the connection to a TLS-protected connection before issuing any login commands. Note that an appropriate trust store must configured so that the client will trust the server's certificate. Defaults to false.

如果设置为true,  则在执行登陆命令前,会使用STRRTTLS命令选择使用TLS方式建连(前提是邮件服务器必须支持TLS方式)。

需要注意的是,在我们的客户端,必须将服务器端的证书配置到我们的信任列表里面(信任列表就是truststore,用来存放信任的证书的,不清楚是什么的需要去度娘一下);

默认值为false;

 

 

发送smtp邮件

下面是阿里云禁用25端口的情况下如何使用465端口smtps协议发送邮件

https://www.unixhot.com/article/303

  • 3
    点赞
  • 20
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值