背景
一般来说,应用系统都需要发送邮件,提供一个认证的邮箱帐号和密码是很常见的。但是,碰到一个特殊情况,客户方是内网直连邮箱服务器的,不需要通过帐号密码认证发送邮件,这样的话,理论上将 mail.smtp.auth
属性配置为 false
就可以了。
测试发现这个技术点还有个小坑,本文将记录下这个小问题,以备将来查看。
mail.smtp.auth 的作用
mail.smtp.auth
是控制邮件发送是是否需要进行登录认证的:
true
表示需要身份验证false
表示不需要身份验证
通过 JavaMailSenderImpl
的 setJavaMailProperties
方法来设置该属性。
两种创建实例方式
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