无法连接到SMTP主机: smtp.gmail.com,端口: 587; 嵌套异常为: java.net.ConnectException: 连接超时: 连接

10

这是应用程序的代码。我一直在尝试使用Eclipse IDE运行它。我也添加了所有必需的Java邮件jar文件,即dsn.jar、imap.jar、mailapi.jar、pop3.jar、smtp.jar和mail.jar。但是会出现以下错误:无法连接到SMTP主机:smtp.gmail.com,端口:587

没有防火墙阻止访问,因为在ping smtp.gmail.com时收到了回复。我甚至尝试过以下方法:

javax.mail.MessagingException: Could not connect to SMTP host: smtp.gmail.com, port: 587; nested exception is: java.net.ConnectException: Connection timed out: connect at com.sun.mail.smtp.SMTPTransport.openServer(SMTPTransport.java:1972) at com.sun.mail.smtp.SMTPTransport.protocolConnect(SMTPTransport.java:642) at javax.mail.Service.connect(Service.java:317) at javax.mail.Service.connect(Service.java:176) at javax.mail.Service.connect(Service.java:125) at javax.mail.Transport.send0(Transport.java:194) at javax.mail.Transport.send(Transport.java:124) at PlainTextEmailSender.sendPlainTextEmail(PlainTextEmailSender.java:50) at PlainTextEmailSender.main(PlainTextEmailSender.java:73) Caused by: java.net.ConnectException: Connection timed out: connect at java.net.DualStackPlainSocketImpl.connect0(Native Method) at java.net.DualStackPlainSocketImpl.socketConnect(Unknown Source) at java.net.AbstractPlainSocketImpl.doConnect(Unknown Source) at java.net.AbstractPlainSocketImpl.connectToAddress(Unknown Source) at java.net.AbstractPlainSocketImpl.connect(Unknown Source) at java.net.PlainSocketImpl.connect(Unknown Source) at java.net.SocksSocketImpl.connect(Unknown Source) at java.net.Socket.connect(Unknown Source) at java.net.Socket.connect(Unknown Source) at com.sun.mail.util.SocketFetcher.createSocket(SocketFetcher.java:319) at com.sun.mail.util.SocketFetcher.getSocket(SocketFetcher.java:233) at com.sun.mail.smtp.SMTPTransport.openServer(SMTPTransport.java:1938)

    package net.codejava.mail;

    import java.util.Date;
    import java.util.Properties;

    import javax.mail.Authenticator;
    import javax.mail.Message;
    import javax.mail.MessagingException;
    import javax.mail.PasswordAuthentication;
    import javax.mail.Session;
    import javax.mail.Transport;
    import javax.mail.internet.AddressException;
    import javax.mail.internet.InternetAddress;
    import javax.mail.internet.MimeMessage;

    public class PlainTextEmailSender {

        public void sendPlainTextEmail(String host, String port,
                final String userName, final String password, String toAddress,
                String subject, String message) throws AddressException,
                MessagingException {

            // sets SMTP server properties
            Properties properties = new Properties();
            properties.put("mail.smtp.host", host);
            properties.put("mail.smtp.port", port);
            properties.put("mail.smtp.auth", "true");
            properties.put("mail.smtp.starttls.enable", "true");

            // creates a new session with an authenticator
            Authenticator auth = new Authenticator() {
                public PasswordAuthentication getPasswordAuthentication() {
                    return new PasswordAuthentication(userName, password);
                }
            };

            Session session = Session.getInstance(properties, auth);

            // creates a new e-mail message
            Message msg = new MimeMessage(session);

            msg.setFrom(new InternetAddress(userName));
            InternetAddress[] toAddresses = { new InternetAddress(toAddress) };
            msg.setRecipients(Message.RecipientType.TO, toAddresses);
            msg.setSubject(subject);
            msg.setSentDate(new Date());
            // set plain text message
            msg.setText(message);

            // sends the e-mail
            Transport.send(msg);

        }

        /**
         * Test the send e-mail method
         *
         */
        public static void main(String[] args) {
            // SMTP server information
            String host = "smtp.gmail.com";
            String port = "587";
            String mailFrom = "user_name";
            String password = "password";

            // outgoing message information
            String mailTo = "email_address";
            String subject = "Hello my friend";
            String message = "Hi guy, Hope you are doing well. Duke.";

            PlainTextEmailSender mailer = new PlainTextEmailSender();

            try {
                mailer.sendPlainTextEmail(host, port, mailFrom, password, mailTo,
                        subject, message);
                System.out.println("Email sent.");
            } catch (Exception ex) {
                System.out.println("Failed to sent email.");
                ex.printStackTrace();
            }
        }
    }

我没有尝试使用telnet客户端进行连接,但我使用cmd检查ping请求到smtp.gmail.com是否有响应。在那里它运行良好。 - zainab rizvi
我按照你的要求提供了异常的完整堆栈跟踪。如果您能帮忙解决这个问题就太好了。 - zainab rizvi
实际上,我想在我的项目中使用它,我想将随机生成的用户ID和密码发送到特定用户的电子邮件地址。但是这个邮件功能好像不起作用 :/ - zainab rizvi
4个回答

5

针对那些仍在寻找简单答案的人,下面是答案:

步骤1: 大多数反病毒程序会阻止计算机通过内部应用程序发送电子邮件。因此,如果出现错误,则必须在调用这些电子邮件发送方法/ API 时禁用您的反病毒程序。

步骤2: 默认情况下,Gmail 禁用 SMTP 访问。要允许应用程序使用您的 Gmail 帐户发送电子邮件,请按照以下步骤操作:

  1. 打开链接:https://myaccount.google.com/security?pli=1#connectedapps
  2. 在安全设置中,将“允许不安全的应用程序”设置为打开

步骤3: 这是我使用过且没有任何问题的代码片段。 来自 EmailService.java 文件:

private Session getSession() {
    //Gmail Host
    String host = "smtp.gmail.com";
    String username = "techdeveloper.aj@gmail.com";
    //Enter your Gmail password
    String password = "";

    Properties prop = new Properties();
    prop.put("mail.smtp.auth", true);
    prop.put("mail.smtp.starttls.enable", "true");
    prop.put("mail.smtp.host", host);
    prop.put("mail.smtp.port", 587);
    prop.put("mail.smtp.ssl.trust", host);

    return Session.getInstance(prop, new Authenticator() {
        @Override
        protected PasswordAuthentication getPasswordAuthentication() {
            return new PasswordAuthentication(username, password);
        }
    });
}

我还写了一篇博客文章,并在GitHub上发布了一个工作应用程序,介绍了以下步骤。请查看:http://softwaredevelopercentral.blogspot.com/2019/05/send-email-in-java.html


4

使用以下 Maven 依赖项,通过 JDK 7 成功通过 Gmail 发送电子邮件,并使用以下 Gmail 设置

前往 Gmail 设置 > 帐户和导入 > 其他 Google 帐户设置 > 并在 登录和安全性 下:

  1. 双重验证:关闭
  2. 允许不安全的应用程序:开启
  3. 应用程序密码:1 个密码(16 个字符长),稍后将当前密码替换为此密码。

使用以下 Maven 依赖项:

spring-core:4.2.2
spring-beans:4.2.2
spring-context:4.2.2
spring-context-support:4.2.2
spring-expression:4.2.2
commons-logging:1.2

<dependency>
    <groupId>javax.mail</groupId>
    <artifactId>mail</artifactId>
    <version>1.4.7</version>
</dependency>

我的源代码是:

import org.springframework.mail.javamail.JavaMailSenderImpl;
import org.springframework.mail.javamail.MimeMessageHelper;

import javax.mail.MessagingException;
import javax.mail.internet.MimeMessage;
import javax.swing.JOptionPane;
import java.util.List;
import java.util.Properties;

public class Email {

    public final void prepareAndSendEmail(String htmlMessage, String toMailId) {

        final OneMethod oneMethod = new OneMethod();
        final List<char[]> resourceList = oneMethod.getValidatorResource();

        //Spring Framework JavaMailSenderImplementation    
        JavaMailSenderImpl mailSender = new JavaMailSenderImpl();
        mailSender.setHost("smtp.gmail.com");
        mailSender.setPort(465);

        //setting username and password
        mailSender.setUsername(String.valueOf(resourceList.get(0)));
        mailSender.setPassword(String.valueOf(resourceList.get(1)));

        //setting Spring JavaMailSenderImpl Properties
        Properties mailProp = mailSender.getJavaMailProperties();
        mailProp.put("mail.transport.protocol", "smtp");
        mailProp.put("mail.smtp.auth", "true");
        mailProp.put("mail.smtp.starttls.enable", "true");
        mailProp.put("mail.smtp.starttls.required", "true");
        mailProp.put("mail.debug", "true");
        mailProp.put("mail.smtp.ssl.enable", "true");
        mailProp.put("mail.smtp.user", String.valueOf(resourceList.get(0)));

        //preparing Multimedia Message and sending
        MimeMessage mimeMessage = mailSender.createMimeMessage();
        try {
            MimeMessageHelper helper = new MimeMessageHelper(mimeMessage, true);
            helper.setTo(toMailId);
            helper.setSubject("I achieved the Email with Java 7 and Spring");
            helper.setText(htmlMessage, true);//setting the html page and passing argument true for 'text/html'

            //Checking the internet connection and therefore sending the email
            if(OneMethod.isNetConnAvailable())
                mailSender.send(mimeMessage);
            else
                JOptionPane.showMessageDialog(null, "No Internet Connection Found...");
        } catch (MessagingException e) {
            e.printStackTrace();
        }

    }

}

希望这能帮助到某些人。

3

就像我说的,你的代码没有任何问题。如果需要测试,可以尝试删除身份验证部分来查看是否可行:

    public void sendPlainTextEmail(String host, String port,
            final String userName, final String password, String toAddress,
            String subject, String message) throws AddressException,
            MessagingException {

        // sets SMTP server properties
        Properties properties = new Properties();
        properties.put("mail.smtp.host", host);
        properties.put("mail.smtp.port", port);
        properties.put("mail.smtp.auth", "true");
        properties.put("mail.smtp.starttls.enable", "true");
// *** BEGIN CHANGE
        properties.put("mail.smtp.user", userName);

        // creates a new session, no Authenticator (will connect() later)
        Session session = Session.getDefaultInstance(properties);
// *** END CHANGE

        // creates a new e-mail message
        Message msg = new MimeMessage(session);

        msg.setFrom(new InternetAddress(userName));
        InternetAddress[] toAddresses = { new InternetAddress(toAddress) };
        msg.setRecipients(Message.RecipientType.TO, toAddresses);
        msg.setSubject(subject);
        msg.setSentDate(new Date());
        // set plain text message
        msg.setText(message);

// *** BEGIN CHANGE
        // sends the e-mail
        Transport t = session.getTransport("smtp");
        t.connect(userName, password);
        t.sendMessage(msg, msg.getAllRecipients());
        t.close();
// *** END CHANGE

    }

这是我每天用来从我的应用程序发送数十封电子邮件的代码,只要smtp.gmail.com:587可以访问,它就百分之百保证可用。


你使用的是哪个 JDK 版本?源代码在Java 8上可以正常工作,但在JDK 7上反复失败。 - ArifMustafa
我正在使用Java 8,但那段代码甚至可以在Java 6上运行。它与所有JavaMail教程实际上是几乎相同的。@ArifMustafa,你遇到了什么错误? - walen
请同时分享您正在使用的Java Mail Jar名称依赖项及其版本! - ArifMustafa
[信息] | - com.sun.mail:javax.mail:jar:1.5.5:编译。但是,如果您像问题中一样遇到“连接超时”的情况,这可能与您的Java代码无关。您应该考虑发布一个新的问题。 - walen
没关系!我一定会找到解决方案的。 - ArifMustafa
显示剩余4条评论

0

请尝试以下步骤:

第二步:从您的设备或应用程序发送邮件

如果您使用 SSL 或 TLS 连接,则可以向任何人发送邮件,使用 smtp.gmail.com。

注意:在开始配置之前,我们建议您为所需的帐户设置应用程序密码。了解更多信息,请参阅使用应用程序密码登录和管理用户的安全设置。

如果您使用 SSL,请在端口 465 上连接到 smtp.gmail.com。(如果您使用 TLS,请在端口 587 上连接。) 使用 Google 用户名和密码进行登录以进行 SSL 或 TLS 连接的身份验证。 确保您使用的用户名已通过首次登录时出现的 CAPTCHA 单词验证测试。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接