如何解决以下问题:javax.mail.MessagingException:无法连接到SMTP主机:SMTP.gmai



我试着增加了通过Android应用程序将订单发送到电子邮件的可能性。但是要被卡住。我在我的谷歌账户中启用了不太安全的访问。起初,我用这种方式。最终,我尝试应用我在这里创建的其他答案中的各种属性,但仍然没有用。

这是我的部分代码:

Properties props = new Properties();
props.put("mail.smtp.user", Utils.EMAIL);
props.put("mail.smtp.host", "smtp.gmail.com");
props.put("mail.smtp.port", "465");
props.put("mail.smtp.starttls.enable","true");
props.put("mail.smtp.debug", "true");
props.put("mail.smtp.auth", "true");
props.put("mail.smtp.socketFactory.port", "465");
props.put("mail.smtp.socketFactory.class", "javax.net.ssl.SSLSocketFactory");
props.put("mail.smtp.socketFactory.fallback", "false");

mSession = Session.getInstance(props,
new javax.mail.Authenticator() {
protected PasswordAuthentication getPasswordAuthentication() {
return new PasswordAuthentication(Utils.EMAIL, Utils.PASSWORD);
}
});
mSession.setDebug(true);
MimeMessage mm = new MimeMessage(mSession);
try {
mm.setFrom(new InternetAddress(Utils.EMAIL));
mm.addRecipient(Message.RecipientType.TO, new InternetAddress(toEmail));
mm.setSubject(mSubject);
mm.setText(mMessage);
Transport transport = mSession.getTransport("smtps");
transport.connect("smtp.gmail.com", Integer.valueOf("465"), Utils.EMAIL, Utils.PASSWORD);
transport.sendMessage(mm, mm.getAllRecipients());
transport.close();

} catch (AddressException e) {
e.printStackTrace();
}  catch (MessagingException e) {
e.printStackTrace();
}

信息:

W/System.err: javax.mail.MessagingException: Could not connect to SMTP host: smtp.gmail.com, port: 465;
nested exception is:
javax.net.ssl.SSLHandshakeException: java.security.cert.CertPathValidatorException: Trust anchor for certification path not found.
W/System.err:     at com.sun.mail.smtp.SMTPTransport.openServer(SMTPTransport.java:1391)
at com.sun.mail.smtp.SMTPTransport.protocolConnect(SMTPTransport.java:412)
at javax.mail.Service.connect(Service.java:288)
at com.example.daukenclub.MailAPI.JavaMailAPI.doInBackground(JavaMailAPI.java:97)
at com.example.daukenclub.MailAPI.JavaMailAPI.doInBackground(JavaMailAPI.java:20)
at android.os.AsyncTask$3.call(AsyncTask.java:378)
at java.util.concurrent.FutureTask.run(FutureTask.java:266)
at android.os.AsyncTask$SerialExecutor$1.run(AsyncTask.java:289)
W/System.err:     at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1167)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:641)
at java.lang.Thread.run(Thread.java:919)
Caused by: javax.net.ssl.SSLHandshakeException: java.security.cert.CertPathValidatorException: Trust anchor for certification path not found.
at com.android.org.conscrypt.ConscryptFileDescriptorSocket.startHandshake(ConscryptFileDescriptorSocket.java:231)
W/System.err:     at com.android.org.conscrypt.ConscryptFileDescriptorSocket.waitForHandshake(ConscryptFileDescriptorSocket.java:476)
at com.android.org.conscrypt.ConscryptFileDescriptorSocket.getInputStream(ConscryptFileDescriptorSocket.java:439)
at com.sun.mail.smtp.SMTPTransport.initStreams(SMTPTransport.java:1449)
at com.sun.mail.smtp.SMTPTransport.openServer(SMTPTransport.java:1366)
... 10 more
W/System.err: Caused by: java.security.cert.CertificateException: java.security.cert.CertPathValidatorException: Trust anchor for certification path not found.
at com.android.org.conscrypt.TrustManagerImpl.verifyChain(TrustManagerImpl.java:674)
at com.android.org.conscrypt.TrustManagerImpl.checkTrustedRecursive(TrustManagerImpl.java:551)
at com.android.org.conscrypt.TrustManagerImpl.checkTrustedRecursive(TrustManagerImpl.java:617)
at com.android.org.conscrypt.TrustManagerImpl.checkTrusted(TrustManagerImpl.java:507)
at com.android.org.conscrypt.TrustManagerImpl.checkTrusted(TrustManagerImpl.java:426)
at com.android.org.conscrypt.TrustManagerImpl.getTrustedChainForServer(TrustManagerImpl.java:354)
at android.security.net.config.NetworkSecurityTrustManager.checkServerTrusted(NetworkSecurityTrustManager.java:94)
W/System.err:     at android.security.net.config.RootTrustManager.checkServerTrusted(RootTrustManager.java:89)
at com.android.org.conscrypt.Platform.checkServerTrusted(Platform.java:224)
at com.android.org.conscrypt.ConscryptFileDescriptorSocket.verifyCertificateChain(ConscryptFileDescriptorSocket.java:407)
at com.android.org.conscrypt.NativeCrypto.SSL_do_handshake(Native Method)
at com.android.org.conscrypt.NativeSsl.doHandshake(NativeSsl.java:387)
at com.android.org.conscrypt.ConscryptFileDescriptorSocket.startHandshake(ConscryptFileDescriptorSocket.java:226)
... 14 more
Caused by: java.security.cert.CertPathValidatorException: Trust anchor for certification path not found.
... 27 more

我将感谢任何有用的建议

我知道一个解决方案,但使用的是okHttp客户端。您需要实现一个sslSocketFactory

val client = OkHttpClient.Builder()
.sslSocketFactory(tlsTocketFactory, tlsTocketFactory.trustManager)
.build()

这是TLSSocketFactory类

import java.io.IOException
import java.net.InetAddress
import java.net.Socket
import java.net.UnknownHostException
import java.security.KeyStore
import java.security.KeyStoreException
import java.security.NoSuchAlgorithmException
import java.util.*
import javax.net.ssl.*
class TLSSocketFactory : SSLSocketFactory() {
private val delegate: SSLSocketFactory
private lateinit var trustManagers: Array<TrustManager>
@Throws(KeyStoreException::class, NoSuchAlgorithmException::class)
private fun generateTrustManagers() {
val trustManagerFactory =
TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm())
trustManagerFactory.init(null as KeyStore?)
val trustManagers =
trustManagerFactory.trustManagers
check(!(trustManagers.size != 1 || trustManagers[0] !is X509TrustManager)) {
("Unexpected default trust managers:"
+ Arrays.toString(trustManagers))
}
this.trustManagers = trustManagers
}
override fun getDefaultCipherSuites(): Array<String> {
return delegate.defaultCipherSuites
}
override fun getSupportedCipherSuites(): Array<String> {
return delegate.supportedCipherSuites
}
@Throws(IOException::class)
override fun createSocket(): Socket {
return enableTLSOnSocket(delegate.createSocket())
}
@Throws(IOException::class)
override fun createSocket(
s: Socket,
host: String,
port: Int,
autoClose: Boolean
): Socket {
return enableTLSOnSocket(delegate.createSocket(s, host, port, autoClose))
}
@Throws(IOException::class, UnknownHostException::class)
override fun createSocket(host: String, port: Int): Socket {
return enableTLSOnSocket(delegate.createSocket(host, port))
}
@Throws(IOException::class, UnknownHostException::class)
override fun createSocket(
host: String,
port: Int,
localHost: InetAddress,
localPort: Int
): Socket {
return enableTLSOnSocket(delegate.createSocket(host, port, localHost, localPort))
}
@Throws(IOException::class)
override fun createSocket(host: InetAddress, port: Int): Socket {
return enableTLSOnSocket(delegate.createSocket(host, port))
}
@Throws(IOException::class)
override fun createSocket(
address: InetAddress,
port: Int,
localAddress: InetAddress,
localPort: Int
): Socket {
return enableTLSOnSocket(delegate.createSocket(address, port, localAddress, localPort))
}
private fun enableTLSOnSocket(socket: Socket): Socket {
if (socket is SSLSocket) {
socket.enabledProtocols = arrayOf(
"TLSv1.1",
"TLSv1.2"
)
}
return socket
}
val trustManager: X509TrustManager?
get() = trustManagers[0] as X509TrustManager
init {
generateTrustManagers()
val context = SSLContext.getInstance("TLS")
context.init(null, trustManagers, null)
delegate = context.socketFactory
}
}

最新更新