解决项目迁移到阿里云后发送不了邮件的问题

最近把项目迁移到阿里云,这几天观察后台日志,发现这么一段异常:

2020-04-09 20:51:39 ERROR MailUtils:228 : 发送邮件失败!com.sun.mail.util.MailConnectException: Couldn't connect to host, port: smtp.163.com, 25; timeout -1;
  nested exception is:
	java.net.ConnectException: Connection timed out (Connection timed out)

然后去调发送邮件的接口,还真的发不了。刚开始也是觉得很奇怪,之前项目在另一台服务器上运行好好的,在本地也可以正常的,为什么一迁移到阿里云服务器上就不行了呢?在阿里云官网上提交工单,他们的售后工程师说了一堆,为了防止垃圾邮件的泛滥,阿里加入了中国什么反垃圾邮件协会,禁用25端口。并给出两种解决方案:

其一:使用SSL安全端口465发送,

其二,使用他们阿里邮箱,他们将25重定向到80端口了。

果断排除第二种,这一来嘛,公司买了第三方邮箱的服务,未到期,重新买阿里邮箱,会造成资源浪费,这二来嘛,还需要修改各个项目涉及到邮件发送的代码。除了核心业务方面的代码,基础配置的代码我一向懒得去改。

所以就毅然决然踏上使用465端口这条路。首先找到项目中邮件发送的代码,可找来找去,没发现涉及到端口方面的配置,于是联系邮件服务提供方,他们说已经开放465端口了的,不信,你用下面的命令测试一下就知道了:

telnet smtp.163.com 465

打开终端,输入以上命令,确实出来welcome的欢迎语。那说明问题不在他们那,于是又找到阿里,阿里小姐姐可真敬业啊,大中午我在吃着午饭,她打来电话,此时已过北京时间12:30。电话里态度也是很好,说了一大堆,挂了电话一想,她话中“是,邮件提供方开放了465端口,但不代表他就使用默认的465端口来发邮件啊,万一他使用25呢”是解决问题的中心思想呀。又联系邮件服务提供方,他们明确告诉我,他们并不能指定使用哪个端口来发送邮件,使用哪个端口发送邮件在于客户端的设定。转了几圈,才猛地发现,原来需要自己编码手动指定邮件发送所使用的端口,如果不指定端口,那么系统将会使用25端口来发送。于是进行编码和测试,终于通了。下面是实现的源码:

/**
 * 使用SSL 465安全方式发送
 * @param toEmail 收件人邮箱
 * @param content 邮件内容
 * @param subject 邮件主题
 */
public static void sendSSLEmail(String toEmail, String content, String subject) {
	boolean isSSL = true;
	String host = "smtp.163.com";
	int port = 465;
	final String from = "[email protected]"; // 发件人的email
	boolean isAuth = true;
	final String password = "123456";

	Properties props = new Properties();
	props.put("mail.smtp.ssl.enable", isSSL); //指定使用SSL方式发送
	props.put("mail.smtp.host", host);        //邮件主机
	props.put("mail.smtp.port", port);       //指定使用465安全端口
	props.put("mail.smtp.auth", isAuth);     //需要验证

	Session session = Session.getDefaultInstance(props, new Authenticator() {
	
	/**
	 * 身份验证
	 */
	@Override
	protected PasswordAuthentication getPasswordAuthentication() {
		return new PasswordAuthentication(from , password);
	}
	});
	
	/**
	 * 实现邮件发送功能
	 */
	try {
		Message message = new MimeMessage(session);
		message.setFrom(new InternetAddress(from));
		message.addRecipient(Message.RecipientType.TO, new InternetAddress(toEmail));
		message.setSubject(subject);
		message.setText(content);
		LOGGER.info("准备发送");
		Transport.send(message);
		LOGGER.info("发送完毕");
	} catch (AddressException e) {
		LOGGER.error(e.getMessage(),e);
	} catch (MessagingException e) {
		LOGGER.error(e.getMessage(),e);
	}

}

注:文中涉及到账号密码请替换为自己的信息。

更新到服务器终于能正常发送邮件了。 

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章