【蠢哭系列】Couldn’t connect to host, port:localhost, 25

Couldn’t connect to host, port:localhost, 25

在测试通过邮件发送验证码的功能时,出现了如下错误:

Mail server connection failed; nested exception is com.sun.mail.util.MailConnectException: 
Couldn't connect to host, port: localhost, 25; timeout -1;

我出现该问题的原因,简化后来说就是JavaMailSend类没有通过IOC容器注入,而是自己new了一个,出现错误情况的复盘代码:

@SpringBootTest
class DemoApplicationTests {
	@Test
	void sendMail() {
		//错误原因在这里!!!
		JavaMailSender mailSender = new JavaMailSenderImpl();
		SimpleMailMessage message = new SimpleMailMessage();
		message.setSubject("木同的小心情验证码");
		message.setFrom("[email protected]");
		message.setTo("[email protected]");
		message.setSentDate(new Date());
		message.setText("您的验证码是:" + 444 + ",五分钟内有效,请勿外泄!");
		mailSender.send(message);
	}
}

正确写法如下:

@SpringBootTest
class DemoApplicationTests {
	@Autowired
	JavaMailSender mailSender;
	@Test
	void sendMail() {
		SimpleMailMessage message = new SimpleMailMessage();
		message.setSubject("木同的小心情验证码");
		message.setFrom("[email protected]");
		message.setTo("[email protected]");
		message.setSentDate(new Date());
		message.setText("您的验证码是:" + 444 + ",五分钟内有效,请勿外泄!");
		mailSender.send(message);
	}
}

简单而言,通过IOC容器获取的对象带有自动配置的配置信息,而自己直接new出来的对象没有配置信息。可以简单写个测试验证一下(这个问题应该都知道…)
直接new一个对象:

@SpringBootTest
class DemoApplicationTests {
	@Test
	void sendMail() {
		JavaMailSenderImpl mailSender = new JavaMailSenderImpl();
		String host = mailSender.getHost();
		int port = mailSender.getPort();
		System.out.println(host + " " + port);
	}
}

此时的结果:

null -1

通过注入获取对象:

@SpringBootTest
class DemoApplicationTests {
	@Autowired
	JavaMailSenderImpl mailSender;

	@Test
	void sendMail() {
		String host = mailSender.getHost();
		int port = mailSender.getPort();
		System.out.println(host + " " + port);
	}
}

此时的结果:

smtp.163.com 465

测试中将接口直接写成了实现类,对功能实现没有影响。

properties文件有关mail的简单配置如下,详细配置信息可以参见官方文档:

  mail:
    host: smtp.163.com
    # SSL端口465994,非SSL端口25
    port: 465
    username: 13026324616@163.com
    password: WFULDPOQIRUFAEDP
    default-encoding: UTF-8
    protocol: smtps

在不指定协议的情况下默认采用smtp协议,此时端口号应为25,否则会出现如下错误:

Got bad greeting from SMTP host: smtp.163.com, port: 465, response: [EOF]. 
Failed messages: javax.mail.MessagingException: Got bad greeting from SMTP host:
 smtp.163.com, port: 465, response: [EOF]

如果指定了协议为smtps,但是端口指定为25,在报错信息中会出现有关协议的错误提示:

javax.net.ssl.SSLException: Unrecognized SSL message, plaintext connection?

另外在刚出现该问题时,搜索了一下该问题,现有的有关该问题的解决方案大致分为三种情况:
1)利用云服务器自己搭建的邮件服务,服务器提供商因为安全等原因关闭了25端口;
没有这种情况的实践经验,与该情况类似的可以参见有关回答。

2)properties中端口号配置错误;
自己尝试的结果是端口号配置错误只会出现前述两种错误,与本次遇到的错误描述不同(前提是使用第三方提供的服务,自己本地搭的没实践过。。。)。

3)本地关闭了25端口,需要将25端口打开。
该情况应该是自己在本地搭建邮箱服务可能碰到的吧,也没有遇到过。。。

你可能感兴趣的:(蠢哭系列)