修复邮件发送
This commit is contained in:
@@ -61,17 +61,21 @@ smsbao.password=your_password
|
|||||||
|
|
||||||
# 邮件配置
|
# 邮件配置
|
||||||
# SMTP 服务器地址
|
# SMTP 服务器地址
|
||||||
spring.mail.host=smtp.chengmail.cn
|
spring.mail.host=smtp.em.dingtalk.com
|
||||||
# SMTP 服务器端口
|
# SMTP 服务器端口(465 为 SSL 加密端口)
|
||||||
spring.mail.port=465
|
spring.mail.port=465
|
||||||
# 发件人邮箱
|
# 发件人邮箱
|
||||||
spring.mail.username=dev@corewing.com
|
spring.mail.username=dev@corewing.com
|
||||||
# 邮箱授权码(不是邮箱密码!需要在邮箱设置中开启 SMTP 服务并获取授权码)
|
# 邮箱授权码(不是邮箱密码!需要在邮箱设置中开启 SMTP 服务并获取授权码)
|
||||||
spring.mail.password=HRTmmNrBRjSxfwAk
|
spring.mail.password=t035gngwYl0xgvZF
|
||||||
# 编码格式
|
# 编码格式
|
||||||
spring.mail.default-encoding=UTF-8
|
spring.mail.default-encoding=UTF-8
|
||||||
# 其他配置
|
# 其他配置
|
||||||
spring.mail.properties.mail.smtp.auth=true
|
spring.mail.properties.mail.smtp.auth=true
|
||||||
spring.mail.properties.mail.smtp.starttls.enable=true
|
# 465 端口使用 SSL 加密,需要启用 SSL
|
||||||
spring.mail.properties.mail.smtp.starttls.required=true
|
spring.mail.properties.mail.smtp.ssl.enable=true
|
||||||
spring.mail.properties.mail.smtp.ssl.enable=false
|
spring.mail.properties.mail.smtp.ssl.required=true
|
||||||
|
# SSL Socket Factory 配置
|
||||||
|
spring.mail.properties.mail.smtp.socketFactory.class=javax.net.ssl.SSLSocketFactory
|
||||||
|
spring.mail.properties.mail.smtp.socketFactory.port=465
|
||||||
|
spring.mail.properties.mail.smtp.socketFactory.fallback=false
|
||||||
|
|||||||
224
src/test/java/com/corewing/app/util/SmtpConnectionTest.java
Normal file
224
src/test/java/com/corewing/app/util/SmtpConnectionTest.java
Normal file
@@ -0,0 +1,224 @@
|
|||||||
|
package com.corewing.app.util;
|
||||||
|
|
||||||
|
import org.junit.jupiter.api.Test;
|
||||||
|
import org.springframework.beans.factory.annotation.Value;
|
||||||
|
import org.springframework.boot.test.context.SpringBootTest;
|
||||||
|
|
||||||
|
import javax.mail.*;
|
||||||
|
import java.util.Properties;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* SMTP 连接诊断测试
|
||||||
|
* 用于排查邮件发送问题
|
||||||
|
*/
|
||||||
|
@SpringBootTest
|
||||||
|
public class SmtpConnectionTest {
|
||||||
|
|
||||||
|
@Value("${spring.mail.host}")
|
||||||
|
private String host;
|
||||||
|
|
||||||
|
@Value("${spring.mail.port}")
|
||||||
|
private int port;
|
||||||
|
|
||||||
|
@Value("${spring.mail.username}")
|
||||||
|
private String username;
|
||||||
|
|
||||||
|
@Value("${spring.mail.password}")
|
||||||
|
private String password;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 测试 SMTP 服务器连接和认证
|
||||||
|
*/
|
||||||
|
@Test
|
||||||
|
public void testSmtpConnection() {
|
||||||
|
System.out.println("========== SMTP 连接诊断 ==========");
|
||||||
|
System.out.println("📧 邮件服务器配置信息:");
|
||||||
|
System.out.println(" SMTP 服务器: " + host);
|
||||||
|
System.out.println(" SMTP 端口: " + port);
|
||||||
|
System.out.println(" 发件人邮箱: " + username);
|
||||||
|
System.out.println(" 授权码长度: " + (password != null ? password.length() : 0) + " 位");
|
||||||
|
System.out.println(" 授权码(隐藏中间部分): " + maskPassword(password));
|
||||||
|
System.out.println();
|
||||||
|
|
||||||
|
// 测试 465 端口(SSL)
|
||||||
|
if (port == 465) {
|
||||||
|
testSslConnection();
|
||||||
|
}
|
||||||
|
// 测试 587 端口(STARTTLS)
|
||||||
|
else if (port == 587) {
|
||||||
|
testStartTlsConnection();
|
||||||
|
}
|
||||||
|
// 测试 25 端口(无加密或 STARTTLS)
|
||||||
|
else if (port == 25) {
|
||||||
|
testPort25Connection();
|
||||||
|
} else {
|
||||||
|
System.out.println("❓ 未知的端口: " + port);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 测试 SSL 连接(465 端口)
|
||||||
|
*/
|
||||||
|
private void testSslConnection() {
|
||||||
|
System.out.println("🔐 正在测试 SSL 连接(端口 465)...");
|
||||||
|
System.out.println();
|
||||||
|
|
||||||
|
Properties props = new Properties();
|
||||||
|
props.put("mail.smtp.host", host);
|
||||||
|
props.put("mail.smtp.port", port);
|
||||||
|
props.put("mail.smtp.auth", "true");
|
||||||
|
props.put("mail.smtp.ssl.enable", "true");
|
||||||
|
props.put("mail.smtp.ssl.required", "true");
|
||||||
|
props.put("mail.smtp.socketFactory.class", "javax.net.ssl.SSLSocketFactory");
|
||||||
|
props.put("mail.smtp.socketFactory.port", port);
|
||||||
|
props.put("mail.smtp.socketFactory.fallback", "false");
|
||||||
|
props.put("mail.smtp.timeout", "10000");
|
||||||
|
props.put("mail.smtp.connectiontimeout", "10000");
|
||||||
|
|
||||||
|
testConnection(props);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 测试 STARTTLS 连接(587 端口)
|
||||||
|
*/
|
||||||
|
private void testStartTlsConnection() {
|
||||||
|
System.out.println("🔐 正在测试 STARTTLS 连接(端口 587)...");
|
||||||
|
System.out.println();
|
||||||
|
|
||||||
|
Properties props = new Properties();
|
||||||
|
props.put("mail.smtp.host", host);
|
||||||
|
props.put("mail.smtp.port", port);
|
||||||
|
props.put("mail.smtp.auth", "true");
|
||||||
|
props.put("mail.smtp.starttls.enable", "true");
|
||||||
|
props.put("mail.smtp.starttls.required", "true");
|
||||||
|
props.put("mail.smtp.ssl.enable", "false");
|
||||||
|
props.put("mail.smtp.timeout", "10000");
|
||||||
|
props.put("mail.smtp.connectiontimeout", "10000");
|
||||||
|
|
||||||
|
testConnection(props);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 测试端口 25 连接
|
||||||
|
*/
|
||||||
|
private void testPort25Connection() {
|
||||||
|
System.out.println("🔓 正在测试端口 25 连接...");
|
||||||
|
System.out.println();
|
||||||
|
|
||||||
|
Properties props = new Properties();
|
||||||
|
props.put("mail.smtp.host", host);
|
||||||
|
props.put("mail.smtp.port", port);
|
||||||
|
props.put("mail.smtp.auth", "true");
|
||||||
|
props.put("mail.smtp.timeout", "10000");
|
||||||
|
props.put("mail.smtp.connectiontimeout", "10000");
|
||||||
|
|
||||||
|
testConnection(props);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 执行连接测试
|
||||||
|
*/
|
||||||
|
private void testConnection(Properties props) {
|
||||||
|
Session session = Session.getInstance(props, new Authenticator() {
|
||||||
|
@Override
|
||||||
|
protected PasswordAuthentication getPasswordAuthentication() {
|
||||||
|
return new PasswordAuthentication(username, password);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
// 开启调试模式
|
||||||
|
session.setDebug(true);
|
||||||
|
|
||||||
|
Transport transport = null;
|
||||||
|
try {
|
||||||
|
System.out.println("⏳ 正在连接到 SMTP 服务器...");
|
||||||
|
transport = session.getTransport("smtp");
|
||||||
|
transport.connect(host, username, password);
|
||||||
|
|
||||||
|
System.out.println();
|
||||||
|
System.out.println("========================================");
|
||||||
|
System.out.println("✅ SMTP 连接成功!");
|
||||||
|
System.out.println("========================================");
|
||||||
|
System.out.println("📝 诊断结果:");
|
||||||
|
System.out.println(" ✓ 服务器地址正确");
|
||||||
|
System.out.println(" ✓ 端口配置正确");
|
||||||
|
System.out.println(" ✓ 用户名正确");
|
||||||
|
System.out.println(" ✓ 授权码正确");
|
||||||
|
System.out.println();
|
||||||
|
System.out.println("💡 邮件配置没有问题,可以正常发送邮件了!");
|
||||||
|
|
||||||
|
} catch (AuthenticationFailedException e) {
|
||||||
|
System.out.println();
|
||||||
|
System.out.println("========================================");
|
||||||
|
System.out.println("❌ 认证失败!");
|
||||||
|
System.out.println("========================================");
|
||||||
|
System.out.println("📝 错误原因:用户名或密码(授权码)错误");
|
||||||
|
System.out.println();
|
||||||
|
System.out.println("💡 解决方案:");
|
||||||
|
System.out.println(" 1. 检查邮箱地址是否正确: " + username);
|
||||||
|
System.out.println(" 2. 确认是否使用授权码而非登录密码");
|
||||||
|
System.out.println(" 3. 登录邮箱管理后台,查找「SMTP设置」或「客户端授权密码」");
|
||||||
|
System.out.println(" 4. 确认是否需要先开启 SMTP 服务");
|
||||||
|
System.out.println(" 5. 重新生成授权码并更新到 application.properties");
|
||||||
|
System.out.println();
|
||||||
|
System.out.println("🔗 常见企业邮箱 SMTP 设置:");
|
||||||
|
System.out.println(" • 腾讯企业邮箱: smtp.exmail.qq.com:465 (SSL)");
|
||||||
|
System.out.println(" • 阿里企业邮箱: smtp.qiye.aliyun.com:465 (SSL)");
|
||||||
|
System.out.println(" • 网易企业邮箱: smtp.qiye.163.com:465 (SSL)");
|
||||||
|
System.out.println();
|
||||||
|
System.out.println("⚠️ 详细错误信息: " + e.getMessage());
|
||||||
|
|
||||||
|
} catch (MessagingException e) {
|
||||||
|
System.out.println();
|
||||||
|
System.out.println("========================================");
|
||||||
|
System.out.println("❌ 连接失败!");
|
||||||
|
System.out.println("========================================");
|
||||||
|
System.out.println("📝 错误类型:" + e.getClass().getSimpleName());
|
||||||
|
System.out.println();
|
||||||
|
System.out.println("💡 可能的原因:");
|
||||||
|
System.out.println(" 1. SMTP 服务器地址错误: " + host);
|
||||||
|
System.out.println(" 2. 端口号错误或被防火墙封禁: " + port);
|
||||||
|
System.out.println(" 3. 网络连接问题");
|
||||||
|
System.out.println(" 4. SSL/TLS 配置不匹配");
|
||||||
|
System.out.println();
|
||||||
|
System.out.println("🔧 建议尝试:");
|
||||||
|
System.out.println(" • 如果当前是 465 端口,尝试改为 587 + STARTTLS");
|
||||||
|
System.out.println(" • 检查防火墙是否封禁了邮件端口");
|
||||||
|
System.out.println(" • 联系邮箱服务商确认正确的 SMTP 配置");
|
||||||
|
System.out.println();
|
||||||
|
System.out.println("⚠️ 详细错误信息: " + e.getMessage());
|
||||||
|
|
||||||
|
} catch (Exception e) {
|
||||||
|
System.out.println();
|
||||||
|
System.out.println("========================================");
|
||||||
|
System.out.println("❌ 未知错误!");
|
||||||
|
System.out.println("========================================");
|
||||||
|
System.out.println("⚠️ 错误信息: " + e.getMessage());
|
||||||
|
e.printStackTrace();
|
||||||
|
|
||||||
|
} finally {
|
||||||
|
if (transport != null && transport.isConnected()) {
|
||||||
|
try {
|
||||||
|
transport.close();
|
||||||
|
} catch (MessagingException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 隐藏密码中间部分
|
||||||
|
*/
|
||||||
|
private String maskPassword(String password) {
|
||||||
|
if (password == null || password.length() <= 4) {
|
||||||
|
return "****";
|
||||||
|
}
|
||||||
|
int showChars = Math.min(2, password.length() / 4);
|
||||||
|
String start = password.substring(0, showChars);
|
||||||
|
String end = password.substring(password.length() - showChars);
|
||||||
|
int maskLength = password.length() - (showChars * 2);
|
||||||
|
String mask = "*".repeat(maskLength);
|
||||||
|
return start + mask + end;
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user