這篇文章分享一下自己把項(xiàng)目部署在阿里云ECS上之后,登錄郵件提醒時(shí)的郵件發(fā)送失敗問(wèn)題,無(wú)法連接發(fā)送郵箱的服務(wù)器。
博主使用的springboot提供的發(fā)送郵件服務(wù),如下所示,為了實(shí)現(xiàn)異步的效果,新開(kāi)了一個(gè)線程來(lái)發(fā)送郵件。
package cn.edu.sgu.www.mhxysy.service.system.impl;
import cn.edu.sgu.www.mhxysy.property.EmailProperties;
import cn.edu.sgu.www.mhxysy.property.SystemSettingsProperties;
import cn.edu.sgu.www.mhxysy.consts.RedisKeyPrefixConst;
import cn.edu.sgu.www.mhxysy.dto.system.UserLoginDTO;
import cn.edu.sgu.www.mhxysy.dto.system.UserUpdateDTO;
import cn.edu.sgu.www.mhxysy.entity.system.User;
import cn.edu.sgu.www.mhxysy.entity.system.UserLoginLog;
import cn.edu.sgu.www.mhxysy.exception.GlobalException;
import cn.edu.sgu.www.mhxysy.feign.FeignService;
import cn.edu.sgu.www.mhxysy.redis.RedisRepository;
import cn.edu.sgu.www.mhxysy.redis.StringRedisUtils;
import cn.edu.sgu.www.mhxysy.restful.ResponseCode;
import cn.edu.sgu.www.mhxysy.service.system.UserService;
import cn.edu.sgu.www.mhxysy.util.IpUtils;
import cn.edu.sgu.www.mhxysy.util.StringUtils;
import cn.edu.sgu.www.mhxysy.util.UserUtils;
import lombok.extern.slf4j.Slf4j;
import org.apache.shiro.authc.UsernamePasswordToken;
import org.apache.shiro.subject.Subject;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.mail.javamail.JavaMailSender;
import org.springframework.mail.javamail.MimeMessageHelper;
import org.springframework.stereotype.Service;
import javax.mail.MessagingException;
import javax.mail.internet.MimeMessage;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
/**
* @author heyunlin
* @version 1.0
*/
@Slf4j
@Service
public class UserServiceImpl implements UserService {
private final FeignService feignService;
private final JavaMailSender javaMailSender;
private final EmailProperties emailProperties;
private final RedisRepository redisRepository;
private final StringRedisUtils stringRedisUtils;
private final SystemSettingsProperties systemSettingsProperties;
@Autowired
public UserServiceImpl(
FeignService feignService,
JavaMailSender javaMailSender,
EmailProperties emailProperties,
RedisRepository redisRepository,
StringRedisUtils stringRedisUtils,
SystemSettingsProperties systemSettingsProperties) {
this.feignService = feignService;
this.javaMailSender = javaMailSender;
this.emailProperties = emailProperties;
this.redisRepository = redisRepository;
this.stringRedisUtils = stringRedisUtils;
this.systemSettingsProperties = systemSettingsProperties;
}
@Override
public void logout() {
// 刪除角色的權(quán)限
redisRepository.delete(UserUtils.getLoginUsername());
// 注銷(xiāo)
UserUtils.getSubject().logout();
}
@Override
public void login(UserLoginDTO loginDTO) {
// 一、驗(yàn)證碼判斷
// 得到用戶輸入的驗(yàn)證碼
String code = loginDTO.getCode();
// 獲取正確的驗(yàn)證碼
String uuid = loginDTO.getUuid();
String key = RedisKeyPrefixConst.PREFIX_CAPTCHA + uuid;
String realCode = stringRedisUtils.get(key);
// 得到的驗(yàn)證碼為空,則獲取驗(yàn)證碼到登錄之間的時(shí)間已經(jīng)過(guò)了3分鐘,驗(yàn)證碼過(guò)期已經(jīng)被刪除
if (realCode == null) {
throw new GlobalException(ResponseCode.BAD_REQUEST, "驗(yàn)證碼已失效,請(qǐng)刷新頁(yè)面重新獲取~");
}
// 驗(yàn)證碼校驗(yàn)
if (!code.equalsIgnoreCase(realCode)) {
throw new GlobalException(ResponseCode.BAD_REQUEST, "驗(yàn)證碼錯(cuò)誤~");
}
// 二、登錄流程
// 得到用戶名
String username = loginDTO.getUsername();
log.debug("用戶{}正在登錄...", username);
// 查詢用戶信息,如果用戶被鎖定,提前退出
User user = feignService.selectByUsername(username);
if (user != null) {
if (user.getEnable()) {
// 1、shiro登錄認(rèn)證
UsernamePasswordToken token = new UsernamePasswordToken(username, loginDTO.getPassword());
Subject subject = UserUtils.getSubject();
subject.login(token);
// 設(shè)置session失效時(shí)間:永不超時(shí)
subject.getSession().setTimeout(-1001);
// 2、修改管理員上一次登錄時(shí)間
User usr = new User();
usr.setId(user.getId());
usr.setLastLoginTime(LocalDateTime.now());
feignService.updateById(usr);
// 3、郵件通知
if (emailProperties.isEnable()) {
new Thread(() -> {
// 定義日期格式
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy年MM月dd日 HH:mm:ss");
MimeMessage message = javaMailSender.createMimeMessage();
MimeMessageHelper helper = new MimeMessageHelper(message);
try {
String text = "您的賬號(hào)" + username + "在廣州登錄了。" +
"[" + LocalDateTime.now().format(formatter) + "]";
helper.setFrom(emailProperties.getFrom());
helper.setTo(emailProperties.getTo());
helper.setText(text);
javaMailSender.send(message);
} catch (MessagingException e) {
e.printStackTrace();
}
}).start();
}
// 4、如果開(kāi)啟了系統(tǒng)日志,添加管理員登錄歷史
if (systemSettingsProperties.isLoginLog()) {
UserLoginLog loginLog = new UserLoginLog();
loginLog.setId(StringUtils.uuid());
loginLog.setUserId(user.getId());
loginLog.setLoginTime(LocalDateTime.now());
loginLog.setLoginIp(IpUtils.getLocalHostAddress());
loginLog.setLoginHostName(IpUtils.getLocalHostName());
feignService.saveLoginLog(loginLog);
}
// 5、從redis中刪除用戶權(quán)限
redisRepository.delete(username);
// 6、查詢用戶的權(quán)限信息,并保存到redis
redisRepository.save(username);
} else {
throw new GlobalException(ResponseCode.FORBIDDEN, "賬號(hào)已被鎖定,禁止登錄!");
}
} else {
throw new GlobalException(ResponseCode.NOT_FOUND, "用戶名不存在~");
}
}
@Override
public void updatePass(UserUpdateDTO userUpdateDTO) {
feignService.updatePass(userUpdateDTO);
}
}
過(guò)了一段時(shí)間之后,后臺(tái)打印出了連接郵箱服務(wù)器超時(shí)的日志。?
Exception in thread "Thread-25" org.springframework.mail.MailSendException: Mail server connection failed; nested exception is 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). Failed messages: 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); message exception details (1) are:
Failed message 1:
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)
at com.sun.mail.smtp.SMTPTransport.openServer(SMTPTransport.java:2210)
at com.sun.mail.smtp.SMTPTransport.protocolConnect(SMTPTransport.java:722)
at javax.mail.Service.connect(Service.java:342)
at org.springframework.mail.javamail.JavaMailSenderImpl.connectTransport(JavaMailSenderImpl.java:518)
at org.springframework.mail.javamail.JavaMailSenderImpl.doSend(JavaMailSenderImpl.java:437)
at org.springframework.mail.javamail.JavaMailSenderImpl.send(JavaMailSenderImpl.java:361)
at org.springframework.mail.javamail.JavaMailSenderImpl.send(JavaMailSenderImpl.java:356)
at cn.edu.sgu.www.mhxysy.service.system.impl.UserServiceImpl.lambda$login$0(UserServiceImpl.java:135)
at java.lang.Thread.run(Thread.java:745)
Caused by: java.net.ConnectException: Connection timed out (Connection timed out)
at java.net.PlainSocketImpl.socketConnect(Native Method)
at java.net.AbstractPlainSocketImpl.doConnect(AbstractPlainSocketImpl.java:350)
at java.net.AbstractPlainSocketImpl.connectToAddress(AbstractPlainSocketImpl.java:206)
at java.net.AbstractPlainSocketImpl.connect(AbstractPlainSocketImpl.java:188)
at java.net.SocksSocketImpl.connect(SocksSocketImpl.java:392)
at java.net.Socket.connect(Socket.java:589)
at java.net.Socket.connect(Socket.java:538)
at com.sun.mail.util.SocketFetcher.createSocket(SocketFetcher.java:335)
at com.sun.mail.util.SocketFetcher.getSocket(SocketFetcher.java:214)
at com.sun.mail.smtp.SMTPTransport.openServer(SMTPTransport.java:2160)
... 8 more
原因是:Couldn't connect to host, port: smtp.163.com, 25
但是通過(guò)終端連接smtp.163.com是成功的
ping smtp.163.com
但是嘗試訪問(wèn)25端口,卻無(wú)響應(yīng)
telnet smtp.163.com 25
于是在網(wǎng)上查找了一些解決方案,最后采用了通過(guò)ssl連接的方式,在原來(lái)的郵件設(shè)置中加入以下設(shè)置文章來(lái)源:http://www.zghlxwxcb.cn/news/detail-729223.html
spring:
mail:
port: 25
host: smtp.163.com
default-encoding: UTF-8
username: xxxxx@163.com
password: xxxxxxxxxxxxx
# 以下是新增的設(shè)置
properties:
mail:
debug: true
smtp:
auth: true
ssl:
trust: smtp.163.com
starttls:
enable: true
required: true
socketFactory:
port: 465
class: javax.net.ssl.SSLSocketFactory
最后重啟服務(wù),登陸的時(shí)候成功發(fā)出了郵件。文章來(lái)源地址http://www.zghlxwxcb.cn/news/detail-729223.html
到了這里,關(guān)于阿里云ECS服務(wù)器無(wú)法發(fā)送郵件問(wèn)題解決方案的文章就介紹完了。如果您還想了解更多內(nèi)容,請(qǐng)?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!