【问题标题】:Sending Email via gmail smtp server in JAVA在 JAVA 中通过 gmail smtp 服务器发送电子邮件
【发布时间】:2013-03-13 22:04:09
【问题描述】:

这段代码有什么问题?不知何故,它进入了Transport.send(message); 行的无限循环,没有错误消息,没有异常,只是可能无限循环(我不知道,因为我等待的时间不超过 5-10 分钟)

final String username = "<mail_name>";
final String password = "<password>";

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", "465");

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("<mail_from>@gmail.com"));
    message.setRecipients(Message.RecipientType.TO,
            InternetAddress.parse("<mail_to>@gmail.com"));
    message.setSubject("Test Subject");
    message.setText("Test");

    Transport.send(message);

    System.out.println("Done");

} catch (MessagingException e) {
    throw new RuntimeException(e);
}

【问题讨论】:

  • 我建议在MessagingException 之后添加一个catch (Exception e){},以查看是否会引发其他类型的异常。还要添加一个finally 块。您还可以添加log4j.xml 并将javax.mail 类设置为DEBUG,看看还会发生什么。
  • 很好的提示,谢谢!会测试它
  • 不幸的是仍在 Transport.send(message) 线上等待...有人可以验证此代码的正确性吗?

标签: java smtp jakarta-mail


【解决方案1】:

使用Simple Java Mail 应该很简单:

Email email = new Email();

email.setFromAddress("lollypop", "lol.pop@somemail.com");
email.addRecipient("C.Cane", "candycane@candyshop.org", RecipientType.TO);
email.setText("We should meet up!");
email.setTextHTML("<b>We should meet up!</b>");
email.setSubject("hey");

new Mailer("smtp.gmail.com", 25, "your user", "your password", TransportStrategy.SMTP_TLS).sendMail(email);
new Mailer("smtp.gmail.com", 587, "your user", "your password", TransportStrategy.SMTP_TLS).sendMail(email);
new Mailer("smtp.gmail.com", 465, "your user", "your password", TransportStrategy.SMTP_SSL).sendMail(email);

如果您启用了双因素登录,则需要从您的 Google 帐户生成application specific password

【讨论】:

    【解决方案2】:

    好的。它比我第一次提出的要复杂一些......总结一下我得到了什么:

    • 有一个非常有用的命令:session.setDebug(true);。如果你设置为真,每一个重要的进程都会被调试到控制台。我建议使用它。
    • 第二台计算机只能使用安全选项,您可以切换这台计算机:Transport transport = session.getTransport("smtps"); 而不是非安全 smtp... JavaMail API 传输对象也将处理端口(分别为 smtp: 587 , smtps: 465)
    • 你也可以使用Transport类的静态方法发送消息和(之前保存,非静态sendMessage方法不会保存消息),但是这次你需要使用javax.mail.Authenticator会话创建,如下所示:

      Session session = Session.getInstance(props,         new javax.mail.Authenticator() {
          protected PasswordAuthentication getPasswordAuthentication() {
              return new PasswordAuthentication("login", "password");
          }
      

      });

    1.4.2 JavaMailApi 对于这个问题除了 1.4.7 版本还有另一个异常...

    如果不使用,则无法使用静态方法进行身份验证。如果你使用实例方法,你可以。

    • 一台计算机有 maven 并获得了 1.4.2 版本的 JavaMail API。第二台电脑有一个下载的库,版本为 1.4.7,我想这也弄乱了东西
    • 第一个comp Netbeans,第二个comp Intellij... +1) 互联网上有很多陈旧且糟糕的示例代码,这使得正确使用此 API 变得更加困难。

    太乱了,但有一些基本概念应该重点关注...

    【讨论】:

      【解决方案3】:

      我在这里进行了一些更改,这对我来说很好用:

      Session session = Session.getInstance(props,null);
      

      你像你一样实例化消息对象。最后:

      Transport transport = session.getTransport("smtp");
      String mfrom = "yourGmailUsernameWithout@"// example laabidiraissi 
      transport.connect("smtp.gmail.com", mfrom, "thepassword");
      transport.sendMessage(message, message.getAllRecipients());
      

      编辑,请您帮我一个忙,复制/粘贴并尝试这个示例并显示它显示的内容:

      package com.test;
      
      import java.util.Properties;
      
      import javax.mail.BodyPart;
      import javax.mail.Message;
      import javax.mail.MessagingException;
      import javax.mail.Multipart;
      import javax.mail.Session;
      import javax.mail.Transport;
      import javax.mail.internet.AddressException;
      import javax.mail.internet.InternetAddress;
      import javax.mail.internet.MimeBodyPart;
      import javax.mail.internet.MimeMessage;
      import javax.mail.internet.MimeMultipart;
      
      import org.junit.Test;
      
      public class EmailService {
      
      @Test
      public void test(){
          Properties props = System.getProperties();
          props.put("mail.smtp.starttls.enable", true); // added this line
          props.put("mail.smtp.host", "smtp.gmail.com");
          props.put("mail.smtp.user", "username");
          props.put("mail.smtp.password", "password");
          props.put("mail.smtp.port", "587");
          props.put("mail.smtp.auth", true);
      
      
      
          Session session = Session.getInstance(props,null);
          MimeMessage message = new MimeMessage(session);
      
          System.out.println("Port: "+session.getProperty("mail.smtp.port"));
      
          // Create the email addresses involved
          try {
              InternetAddress from = new InternetAddress("username");
              message.setSubject("Yes we can");
              message.setFrom(from);
              message.addRecipients(Message.RecipientType.TO, InternetAddress.parse("receivermail"));
      
              // Create a multi-part to combine the parts
              Multipart multipart = new MimeMultipart("alternative");
      
              // Create your text message part
              BodyPart messageBodyPart = new MimeBodyPart();
              messageBodyPart.setText("some text to send");
      
              // Add the text part to the multipart
              multipart.addBodyPart(messageBodyPart);
      
              // Create the html part
              messageBodyPart = new MimeBodyPart();
              String htmlMessage = "Our html text";
              messageBodyPart.setContent(htmlMessage, "text/html");
      
      
              // Add html part to multi part
              multipart.addBodyPart(messageBodyPart);
      
              // Associate multi-part with message
              message.setContent(multipart);
      
              // Send message
              Transport transport = session.getTransport("smtp");
              transport.connect("smtp.gmail.com", "username", "password");
              System.out.println("Transport: "+transport.toString());
              transport.sendMessage(message, message.getAllRecipients());
      
      
          } catch (AddressException e) {
              // TODO Auto-generated catch block
              e.printStackTrace();
          } catch (MessagingException e) {
              // TODO Auto-generated catch block
              e.printStackTrace();
          }
      }
      }
      

      【讨论】:

      • 谢谢,但 mail.smtp.auth 属性已经存在...而且我也尝试过使用其他端口。
      • 对不起 auth 属性,这是我的错,我没看到。
      • 如果尝试使用 25 或 587 端口,无论如何检查您的解决方案...线程“main”中的异常 java.lang.RuntimeException:javax.mail.MessagingException:无法连接到 SMTP 主机: smtp.gmail.com,端口:25;嵌套异常是:java.net.ConnectException:连接被拒绝:连接
      • 还是一样的异常,会不会是我的网络配置不对?
      • 终于有好消息了,我们有一些例外。你的例外是经典的:stackoverflow.com/questions/7158951/…
      【解决方案4】:

      我可以重现您问题中描述的行为并修复它。

      send 方法卡在

      SMTPTransport(Service).connect(String, int, String, String) line: 308   
      

      连接不成功,因为您的 gmail smtp 主机端口错误:465

      改成587

      props.put("mail.smtp.port", "587");
      

      它会起作用的。

      【讨论】:

      • 是的,不知道我为什么要骑465端口,但无论如何,它仍然无法正常工作:(
      • 您现在遇到什么异常/错误?您的 java.exe 是否允许通过防火墙?
      • This:java.lang.RuntimeException: javax.mail.MessagingException: 无法连接到 SMTP 主机:smtp.gmail.com,端口:25;嵌套异常是:java.net.ConnectException:连接被拒绝:连接我关闭了整个 Windows 防火墙..
      • 您的应用似乎不支持 SSL。 smtp.gmail.com 需要安全连接,否则您将不得不选择另一个主机 see google support page。您可能需要通过获取支持安全协议smtpsTransport 实例来明确指定它,并使用它来发送您的消息。请参考accepted answer for this question
      猜你喜欢
      • 2022-01-09
      • 2014-10-15
      • 1970-01-01
      • 1970-01-01
      • 2018-10-17
      • 2016-09-07
      • 1970-01-01
      相关资源
      最近更新 更多