我正在尝试通过 Gmail SMTP 服务器使用 JavaMail 发送电子邮件。这是代码:
final String username = "mygmail@gmail.com";
final String password = "mygmailpassword";
Properties props = new Properties();
props.put("mail.smtp.auth", true);
props.put("mail.smtp.starttls.enable", true);
props.put("mail.smtp.host", "smtp.gmail.com");
props.put("mail.smtp.port", "587");
Session session = Session.getInstance(props,
new javax.mail.Authenticator() {
protected PasswordAuthentication getPasswordAuthentication() {
return new PasswordAuthentication(username, password);
}
}
);
try {
Message message = new MimeMessage(session);
message.setFrom(new InternetAddress("no-reply@gmail.com"));
message.setRecipients(Message.RecipientType.TO,
InternetAddress.parse("test@gmail.com"));
message.setSubject("Testing Subject");
message.setText("Dear Mail Crawler," + "\n\n No spam to my email, please!");
Transport.send(message);
System.out.println("Done");
} catch (MessagingException e) {
throw new RuntimeException(e);
}
返回此错误:
无法将套接字转换为 TLS;
完整的堆栈跟踪:
线程“main”中的异常 java.lang.RuntimeException:javax.mail.MessagingException:无法将套接字转换为 TLS;嵌套异常是:javax.net.ssl.SSLHandshakeException:sun.security.validator.ValidatorException:PKIX 路径构建失败:sun.security.provider.certpath.SunCertPathBuilderException:无法在 Test.main(Test .java:43) 原因:javax.mail.MessagingException:无法将套接字转换为 TLS;嵌套异常是:javax.net.ssl.SSLHandshakeException:sun.security.validator.ValidatorException:PKIX 路径构建失败:sun.security.provider.certpath.SunCertPathBuilderException:无法在 com.sun.mail 中找到请求目标的有效证书路径.smtp.SMTPTransport.startTLS(SMTPTransport.java:1907) 在 com.sun.mail.smtp.SMTPTransport.protocolConnect(SMTPTransport.java:666) 在 javax.mail.Service.connect(Service.java:317) 在 javax。 mail.Service.connect(Service.java:176) 在 javax.mail.Service.connect(Service.java:125) 在 javax.mail.Transport.send0(Transport.java:194) 在 javax.mail.Transport.send (Transport.java:124) at Test.main(Test.java:38) 原因:javax.net.ssl.SSLHandshakeException:sun.security.validator.ValidatorException:PKIX 路径构建失败:sun.security.provider.certpath。 SunCertPathBuilderException:无法在 com.sun.net.ssl.internal 的 com.sun.net.ssl.internal.ssl.Alerts.getSSLException(Alerts.java:174) 处找到请求目标的有效证书路径。 ssl.SSLSocketImpl.fatal(SSLSocketImpl.java:1649) 在 com.sun.net.ssl.internal.ssl.Handshaker.fatalSE(Handshaker.java:241) 在 com.sun.net.ssl.internal.ssl.Handshaker。 com.sun.net.ssl.internal.ssl.ClientHandshaker.serverCertificate(ClientHandshaker.java:1206) 的致命SE(Handshaker.java:235) com.sun.net.ssl.internal.ssl.ClientHandshaker.processMessage(ClientHandshaker. java:136) 在 com.sun.net.ssl.internal.ssl.Handshaker.processLoop(Handshaker.java:593) 在 com.sun.net.ssl.internal.ssl.Handshaker.process_record(Handshaker.java:529)在 com.sun.net.ssl.internal.ssl.SSLSocketImpl.readRecord(SSLSocketImpl.java:893) 在 com.sun.net.ssl.internal.ssl.SSLSocketImpl.performInitialHandshake(SSLSocketImpl.java:1138) 在 com.sun .net.ssl.internal.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:1165) 在 com.sun.net.ssl.internal.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:1149) 在 com.sun.mail.util .SocketFetcher.configureSSLSocket(SocketFetcher.java:549) 在 com.sun.mail.util.SocketFetcher.start TLS(SocketFetcher.java:486) at com.sun.mail.smtp.SMTPTransport.startTLS(SMTPTransport.java:1902) ... 7 更多原因:sun.security.validator.ValidatorException:PKIX 路径构建失败:sun. security.provider.certpath.SunCertPathBuilderException:无法在 sun.security.validator.PKIXValidator.engineValidate(PKIXValidator.java:217) 的 sun.security.validator.PKIXValidator.doBuild(PKIXValidator.java:323) 中找到请求目标的有效认证路径) 在 sun.security.validator.Validator.validate(Validator.java:218) 在 com.sun.net.ssl.internal.ssl.X509TrustManagerImpl.validate(X509TrustManagerImpl.java:126) 在 com.sun.net.ssl。 internal.ssl.X509TrustManagerImpl.checkServerTrusted(X509TrustManagerImpl.java:209) 在 com.sun.net.ssl.internal.ssl.X509TrustManagerImpl.checkServerTrusted(X509TrustManagerImpl.java:249) 在 com.sun.net.ssl.internal.ssl。 ClientHandshaker.serverCertificate(ClientHandshaker.java:1185) ... 17 更多原因:sun.security.provider.certpath.SunCertPathBuilderException :无法在 sun.security 的 java.security.cert.CertPathBuilder.build(CertPathBuilder.java:238) 的 sun.security.provider.certpath.SunCertPathBuilder.engineBuild(SunCertPathBuilder.java:174) 中找到请求目标的有效认证路径.validator.PKIXValidator.doBuild(PKIXValidator.java:318) ... 23 更多
props.put("mail.smtp.ssl.trust", "smtp.gmail.com");
我禁用了 avast 防病毒软件 10 分钟并使其正常工作。
确保您的防病毒程序没有干扰,并确保将排除项添加到您的防火墙中。
当用于发送电子邮件的默认 SSL 协议设置为 TLSv1 并且 smtp 服务器不再支持此协议时,我遇到了类似的问题。诀窍是使用更新的协议:
mail.smtp.ssl.protocols=TLSv1.2
@carlos 的第一个答案对我有用:
session.getProperties().put("mail.smtp.ssl.trust", "smtp.gmail.com");
我已经测试了下面的属性并且对我来说也很完美:
session.getProperties().put("mail.smtp.starttls.enable", "true");
仅这两个属性就解决了这类问题,但我保证我同时使用了这两个属性。
在我的情况下,问题是通过删除该行来解决的
prop.put("mail.smtp.starttls.enable", "true");
这可能是因为电子邮件服务器上的一些 ssl 配置错误,我不确定。电子邮件服务器管理员从不承认这一点,总是责怪托管服务提供商 :)
经过一整天的搜索,我禁用了 Avast 10 分钟和 Windows 防火墙(重要),一切都开始工作了!
这是我的错误:
Mail server connection failed; nested exception is javax.mail.MessagingException: Could not convert socket to TLS; nested exception is: javax.net.ssl.SSLHandshakeException: sun.security.validator.ValidatorException: PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target. Failed messages: javax.mail.MessagingException: Could not convert socket to TLS; nested exception is: javax.net.ssl.SSLHandshakeException: sun.security.validator.ValidatorException: PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target
以下是如何通过向 SMTP 端口 587(或您的应用程序使用的任何端口)添加排除项来解决 Avast 19.8.2393 中的问题:
打开 Avast 点击“设置”点击“疑难解答”,然后点击“打开旧设置”
https://i.stack.imgur.com/XZww0.png
再次单击“疑难解答”,向下滚动到“重定向设置”并删除您的应用使用的端口。
https://i.stack.imgur.com/oWxtD.png
就我而言,我刚刚从 SMTP 端口中删除了 587。
现在我可以使用 Avast 并打开我的 Windows 防火墙(无需为防火墙添加额外的排除项)。
这是我的 application.properties 电子邮件属性:
###### I am using a Google App Password which I generated in my Gmail Security settings ######
spring.mail.host = smtp.gmail.com
spring.mail.port = 587
spring.mail.protocol = smtp
spring.mail.username = gmail account
spring.mail.password = password
spring.mail.properties.mail.smtp.auth=true
spring.mail.properties.mail.smtp.starttls.enable=true
spring.mail.properties.mail.smtp.connectiontimeout=5000
spring.mail.properties.mail.smtp.timeout=5000
spring.mail.properties.mail.smtp.writetimeout=5000
上面的 application.properties 对我来说很棒:
spring.mail.properties.mail.smtp.starttls.enable=true
spring.mail.properties.mail.smtp.starttls.required=true
spring.mail.properties.mail.smtp.auth=true
spring.mail.properties.mail.smtp.ssl.trust=smtp.gmail.com
如果应用程序不支持 SMTP 主机正在使用的 TLS 版本,也可能出现这种情况。
例如,当您的应用程序(或使用较旧的 javax.mail JAR 的 java 程序)仅支持 TLSv1.1 时,尝试配置使用 TLSv1.2 而没有回退的 SMTP 服务器。
检查您是否拥有所有这些字段
Properties props = new Properties();
props.put("mail.smtp.host", "smtp.gmail.com");
props.put("mail.smtp.port", "587");
props.put("mail.smtp.auth", "true");
props.put("mail.smtp.ssl.protocols", "TLSv1.2");
props.put("mail.smtp.starttls.enable", "true");
尝试将端口更改为 465
mail.smtp.socketFactory.port=465
mail.smtp.port=465
这取决于“嵌套异常”。如果嵌套异常是“没有适当的协议”,则在系统属性中指定协议:
-Dmail.smtp.ssl.protocols=TLSv1.2
我看到有些人建议在创建 STMP 会话的代码中设置它,但是如果您想在将来更新该值,则需要进行修补和部署。使用系统属性允许您在不更改代码的情况下对其进行更新。
如果您的上下文是 android 应用程序,请确保您的 android 设备时间设置为当前日期和时间。潜在的例外是“SSL 证书未通过身份验证”。
是的,它适用于本地主机:
props.put("mail.smtp.ssl.trust", "smtp.gmail.com");
该错误仅在本地主机上引发,因此您也应该在远程服务器上尝试。通常,上面提到的代码片段在没有 ssl.trust
属性的情况下运行良好
这是工作解决方案兄弟。有保证
1)首先打开您要从中发送邮件的gmail帐户,例如“xyz@gmail.com”
2) 在 https://support.google.com/accounts/answer/6010255?hl=en 下方打开此链接
3) 单击“我的帐户”中的“转到“安全性较低的应用程序”部分。”选项
4)然后打开它
5)就是这样(:
这是我的代码
import javax.mail.*;
import javax.mail.internet.*;
import java.util.*;
public class SendEmail {
final String senderEmailID = "Sender Email id";
final String senderPassword = "Sender Pass word";
final String emailSMTPserver = "smtp.gmail.com";
final String emailServerPort = "465";
String receiverEmailID = null;
static String emailSubject = "Test Mail";
static String emailBody = ":)";
public SendEmail(String receiverEmailID, String emailSubject, String emailBody)
{
this.receiverEmailID=receiverEmailID;
this.emailSubject=emailSubject;
this.emailBody=emailBody;
Properties props = new Properties();
props.put("mail.smtp.user",senderEmailID);
props.put("mail.smtp.host", emailSMTPserver);
props.put("mail.smtp.port", emailServerPort);
props.put("mail.smtp.starttls.enable", "true");
props.put("mail.smtp.auth", "true");
props.put("mail.smtp.socketFactory.port", emailServerPort);
props.put("mail.smtp.socketFactory.class","javax.net.ssl.SSLSocketFactory");
props.put("mail.smtp.socketFactory.fallback", "false");
SecurityManager security = System.getSecurityManager();
try
{
Authenticator auth = new SMTPAuthenticator();
Session session = Session.getInstance(props, auth);
MimeMessage msg = new MimeMessage(session);
msg.setText(emailBody);
msg.setSubject(emailSubject);
msg.setFrom(new InternetAddress(senderEmailID));
msg.addRecipient(Message.RecipientType.TO,
new InternetAddress(receiverEmailID));
Transport.send(msg);
System.out.println("Message send Successfully:)");
}
catch (Exception mex)
{
mex.printStackTrace();
}
}
public class SMTPAuthenticator extends javax.mail.Authenticator
{
public PasswordAuthentication getPasswordAuthentication()
{
return new PasswordAuthentication(senderEmailID, senderPassword);
}
}
public static void main(String[] args) {
SendEmail mailSender;
mailSender = new SendEmail("Receiver Email id","Testing Code 2 example","Testing Code Body yess");
}
}
检查 JavaMail 库的版本(mail.jar 或 javax.mail.jar)。也许你需要一个更新的。从此处下载最新版本:https://javaee.github.io/javamail/
application.properties
中的以下一组属性对我有用:
spring.mail.host=smtp.gmail.com
spring.mail.port=587
spring.mail.username=<gmail_id>
spring.mail.password=<gmail_password>
spring.mail.properties.mail.smtp.ssl.trust=smtp.gmail.com
spring.mail.properties.mail.smtp.auth=true
spring.mail.properties.mail.smtp.starttls.enable=true
spring.mail.properties.mail.smtp.starttls.required=true
请注意,如果您为您的 Gmail 帐户启用了两步验证,那么上述配置中的 gmail_password
不应是普通密码,而是为您的 Google 帐户生成的 16 个字符的应用程序密码。按照此 link 查看详细信息并生成您的 Google 应用密码。
就我而言,我使用的是 OpenJDK,当我切换到 OracleJDK 时,问题得到了解决。
主要答案:
props.put("mail.smtp.ssl.trust", "smtp.gmail.com");
仅在我删除以下内容后才起作用:
mail.smtp.socketFactory.class=javax.net.ssl.SSLSocketFactory
尝试使用 JavaMail 附带的 smtpsend 程序,如 here 所述。如果以同样的方式失败,则说明您的 JDK 配置或网络配置有问题。
是什么帮助我解决了这个问题,并且在此之前我已经尝试过一切,是将我安装的 jre 配置为 JRE 1.8。
Eclipse 中的步骤:Windows>preferences>java>installed JRE>jre1.8.0
如果设置为 jdk,则切换到 jre(这是最新 Java 版本默认设置的)。
mail.smtp.ssl.trust
如果已设置且未指定套接字工厂,则启用 MailSSLSocketFactory。如果设置为“*”,则所有主机都受信任。如果设置为以空格分隔的主机列表,则这些主机是受信任的。否则,信任取决于服务器提供的证书。props.put("mail.smtp.ssl.trust", "*");
成功了