JavaMailSenderImpl 避坑攻略

背景

一般来说,应用系统都需要发送邮件,提供一个认证的邮箱帐号和密码是很常见的。但是,碰到一个特殊情况,客户方是内网直连邮箱服务器的,不需要通过帐号密码认证发送邮件,这样的话,理论上将 mail.smtp.auth 属性配置为 false 就可以了。

测试发现这个技术点还有个小坑,本文将记录下这个小问题,以备将来查看。

mail.smtp.auth 的作用

mail.smtp.auth 是控制邮件发送是是否需要进行登录认证的:

  • true 表示需要身份验证
  • false 表示不需要身份验证

通过 JavaMailSenderImplsetJavaMailProperties 方法来设置该属性。

两种创建实例方式

JavaMailSenderImpl 的创建方式有两种。

第一种,Spring 配置方式:

<bean id="mailSender"  
    class="org.springframework.mail.javamail.JavaMailSenderImpl">  
    <property name="host" value="${mail.host}" />
    <property name="javaMailProperties">  
     <props>  
         <prop key="mail.smtp.auth">false</prop>  
         <prop key="mail.smtp.timeout">${mail.timeout}</prop>
     </props>  
 </property>
</bean>

第二种,直接创建对象:

JavaMailSenderImpl mailSenderImpl = new JavaMailSenderImpl()
Properties prop = new Properties();
prop.put("mail.smtp.auth","false");
prop.put("mail.smtp.timeout","5000");
mailSenderImpl.setJavaMailProperties(prop);
mailSenderImpl.setHost(host);

非认证方式,就不要设置认证帐号信息,否则会画蛇添足导致异常。

实例分析

注入的对象直接 new 的对象对本质是一样的:
在这里插入图片描述
跟踪调试发现,两种方式创建的实例对象,属性基本上是一样的,但是注入的实例就是没办法正常发送邮件。这究竟为什么呢?

最终发现一个问题:邮箱配置的时候,做了一个校验动作,会向配置的邮箱发送一封邮件。虽然邮件发送时不需要设置认证帐号密码,但是如果输入一个错误的邮箱地址,是无法发送成功的。

邮件发送时的各种异常

第一,邮件发送时,虽然不需要帐号认证,但是发件箱地址必须跟 host 邮箱服务器是相同类型,比如 smtp.163.com 但是输入的发件箱地址 [email protected] 时,就会报下面的异常:

com.sun.mail.smtp.SMTPSenderFailedException: 553 Local user only,163 smtp11

第二,设置 mail.smtp.auth=false 后,同时又设置了认证邮箱帐号和密码,那么等价于 mail.smtp.auth=true 了。此时,如果认证帐号密码信息错误,会报异常:

org.springframework.mail.MailAuthenticationException:
 Authentication failed; nested exception is javax.mail.
 AuthenticationFailedException: 535 5.7.3 Authentication unsuccessful

猜你喜欢

转载自blog.csdn.net/wojiushiwo945you/article/details/105275983