问题描述
今天公司一台服务器无法发送邮件给客户
于是看了一下日志报了以下错误
org.springframework.mail.MailSendException: Mail server connection failed; nested exception is javax.mail.MessagingException: Could not connect to SMTP host: smtp.aliyun.com, port: 25;
telnet 了一下邮箱的确不通
不对呀,公司其他几台ECS服务器上面的为什么好使?至此本人已懵逼
中间折腾了好几个小时,又提了工单,闹心的过程不说了。
最后确定问题是由于阿里云ECS服务器把25端口封锁了
那为什么只有这一台不好使?原因在于2016年9月底以后新购买的服务器才会封锁此端口,这台是后买的其他几台都是老服务器。
解决方法
如果想继续发送邮件只能使用SMTPS协议465端口
简单解释一下SMTPS协议是什么鬼
25端口(SMTP):25端口为SMTP(Simple Mail Transfer Protocol,简单邮件传输协议)服务所开放的,是用于发送邮件。
465端口(SMTPS):465端口是为SMTPS(SMTP-over-SSL)协议服务开放的,这是SMTP协议基于SSL安全协议之上的一种变种协议,它继承了SSL安全协议的非对称加密的高度安全可靠性,可防止邮件泄露。SMTPS和SMTP协议一样,也是用来发送邮件的,只是更安全些,防止邮件被黑客截取泄露,还可实现邮件发送者抗抵赖功能。防止发送者发送之后删除已发邮件,拒不承认发送过这样一份邮件。
好吧,现在开始代码改造吧。
package com.plsoft.pmall.utils;
import com.plsoft.pmall.ProjectEnvironment;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.mail.javamail.JavaMailSenderImpl;
import org.springframework.mail.javamail.MimeMessageHelper;
import javax.mail.*;
import javax.mail.internet.MimeMessage;
import java.io.IOException;
import java.io.InputStream;
import java.util.Properties;
/** SendMail - 发送邮件
*
* @version 1.0
*/
public class SendMail {
private static Logger logger = LoggerFactory.getLogger(SendMail.class);
//单例模式
private static SendMail sendMail = null;
//发送设置 由于始终从公司邮箱发送,所以只创建一套发送设置
private JavaMailSenderImpl sender = new JavaMailSenderImpl();
//发件人邮箱
private String from = "";
/**
* 私有化构造函数
*/
private SendMail(){
try{
//从配置文件获取参数
InputStream inputStream = SendMail.class.getClassLoader().getResourceAsStream(ProjectEnvironment.getPropertiesFileName("application"));
Properties applicationProperties = new Properties();
applicationProperties.load(inputStream);
String host = applicationProperties.getProperty("host");
String username = applicationProperties.getProperty("user");
String password = applicationProperties.getProperty("pwd");
from = applicationProperties.getProperty("from");
sender.setHost(host);//SMTP服务器地址
sender.setPort(465); //使用SMTPS协议465端口
sender.setUsername(username);//邮箱登陆用户名
sender.setPassword(password);//邮箱登录密码
Properties properties = new Properties();
properties.put("mail.smtp.auth", "true");//登录服务器是否需要认证
properties.setProperty("mail.smtp.socketFactory.class", "javax.net.ssl.SSLSocketFactory");//SSL证书Socket工厂
properties.setProperty("mail.smtp.socketFactory.port", "465"); //使用SMTPS协议465端口
sender.setJavaMailProperties(properties);
}catch (IOException e){
e.printStackTrace();
}
}
/**
* 获取实例
* @return
* @throws IOException
*/
public static SendMail getSendMail(){
if(sendMail == null){
return new SendMail();
}else{
return sendMail;
}
}
/**
* 发送邮件
* @param to 收件人邮箱
* @param subject 邮件标题
* @param content 邮件内容
*/
public void send(String to,String subject,String content) {
try {
MimeMessage mailMessage = sender.createMimeMessage();
MimeMessageHelper messageHelper = new MimeMessageHelper(mailMessage,"utf-8");
messageHelper.setFrom(from);//发件人邮箱
messageHelper.setTo(to);//收件人邮箱
messageHelper.setSubject(subject);//邮件标题
messageHelper.setText(content,true);//邮件内容,true表示启动HTML格式的邮件
sender.send(mailMessage);//发送邮件
logger.info("邮件\"" + subject + "\"已发送至" + to + "邮箱");
} catch (MessagingException e) {
e.printStackTrace();
}
}
}
改造后经测试组测试邮件发送正常!
这理其实顺带还解决了另一个问题,原来使用SMTP协议时QQ邮箱总判定为垃圾邮件,自从换了SMTPS协议之后就不会再被误判为垃圾邮件了。