阿里云使用springmail发送邮件超时 Connection timed out

原创 2018-01-08 17:11 阅读(1877)次

我在项目里使用spring mail发送邮件,测试环境中(windows)下是正常的,但部署到阿里云linux centos6.8下一直报连接超时:


具体代码配置如下:

@Service("emailSendService")
public class EMailSendService implements IEMailSendService {
	@Resource
	public JavaMailSenderImpl mailSender;
	@Resource
	public SimpleMailMessage mailMessage;
	@Resource
	private IUserDao userDao;
	protected final Logger logger = LoggerFactory.getLogger(this.getClass());
	public boolean SendEmail(String recevireceiver[], String subject, String text) {
		mailMessage.setSubject(subject);
		mailMessage.setText(text);
		mailMessage.setTo(recevireceiver);
		try {
			logger.info("邮件发送中。。。");
			mailSender.send(mailMessage);
			logger.info("邮件发送成功!");
			return true;
		} catch (Exception e) {
			logger.info("邮件发送失败"+e.getMessage());
			e.printStackTrace();
			return false;
		}
	}
}

spring-email.xml配置:

<bean id="mailMessage" class="org.springframework.mail.SimpleMailMessage">  
        <property name="from" value="${mail.from}">  
            <!-- 设置发送方-->  
        </property>  
    </bean>  
      
    <!-- 申明JavaMailSenderImpl对象 -->  
    <bean id="mailSender" class="org.springframework.mail.javamail.JavaMailSenderImpl">  
        <property name="defaultEncoding" value="UTF-8" />  
        <property name="host" value="${mail.host}" />  
        <property name="username" value="${mail.username}" />  
        <property name="password" value="${mail.password}" />  
        <property name="javaMailProperties">  
            <props>  
                <!-- 设置认证开关 -->  
                <prop key="mail.smtp.auth">true</prop>  
                <!-- 启动调试开关 -->  
                <prop key="mail.debug">false</prop>  
            </props>  
        </property>  
    </bean>  

email.properties:

mail.host=smtp.qq.com
mail.username=xxxxx@qq.com
mail.password=xxxxx
mail.from=xxxx@qq.com

解决过程:

1.图中报smtp.qq.com的端口25连接超时,于是我telnet smtp.qq.com 25看了下(如果没有安装就用yum install telnet安装下)

发现是连不通的,于是百度了下,发现是阿里云限制了25端口,就是为了限制垃圾邮件

2.于是我修改了spring-mail.xml使用465端口发送,配置如下:

<bean id="mailSender" class="org.springframework.mail.javamail.JavaMailSenderImpl">  
        <property name="defaultEncoding" value="UTF-8" />  
        <property name="host" value="${mail.host}" />  
        <property name="username" value="${mail.username}" />  
        <property name="password" value="${mail.password}" />  
        <property name="javaMailProperties">  
            <props>  
                <!-- 设置认证开关 -->  
                <prop key="mail.smtp.auth">true</prop>  
                <!-- 启动调试开关 -->  
                <prop key="mail.debug">false</prop>  
                <prop key="mail.smtp.starttls.enable">false</prop>
                <prop key="mail.smtp.socketFactory.port">465</prop>
                <prop key="mail.smtp.socketFactory.class">javax.net.ssl.SSLSocketFactory</prop>
                <prop key="mail.smtp.socketFactory.fallback">false</prop>
            </props>  
        </property>  
    </bean>

再次发送,新的问题又来了,报错:javax.mail.MessagingException: 501 Syntax: HELO hostname

找了下其他人的解决办法,原因是Javamail 在提取本地 hostname 的时候会 dig 改 hostname ,然后以改 ip 发送邮件。
由于 hostname 对应的 ip 地址, linux 无法解析(如果是 windows 则无这个问题, windows 利用 netbios 协议去获得该主机的 ip 地址)到本机 hostname 的 ip ,导致 javamail 无法调用发送 ip 

3.使用hostname查看自己机器的hostname,并把hostname加入到/etc/hosts的127.0.0.1里,就可以了,发送成功!!!

最终加的配置就只有:

<prop key="mail.smtp.starttls.enable">false</prop>
<prop key="mail.smtp.socketFactory.port">465</prop>
 <prop key="mail.smtp.socketFactory.class">javax.net.ssl.SSLSocketFactory</prop>
<prop key="mail.smtp.socketFactory.fallback">false</prop>

并把hostname加入到/etc/hosts的127.0.0.1里就OK了

注意465为ssl端口,如果有需要的话,需要将协议改成smtps