在 JAVA 中通过 gmail smtp 服务器发送电子邮件
Posted
技术标签:
【中文标题】在 JAVA 中通过 gmail smtp 服务器发送电子邮件【英文标题】:Sending Email via gmail smtp server in JAVA 【发布时间】: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) 线上等待...有人可以验证此代码的正确性吗?
【参考方案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:连接被拒绝:连接 还是一样的异常,会不会是我的网络配置不对? 终于有好消息了,我们有一些例外。你的例外是经典的:***.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。您可能需要通过获取支持安全协议smtps
的Transport
实例来明确指定它,并使用它来发送您的消息。请参考accepted answer for this question以上是关于在 JAVA 中通过 gmail smtp 服务器发送电子邮件的主要内容,如果未能解决你的问题,请参考以下文章
使用 Gmail 在 codeigniter 中通过电子邮件类发送电子邮件
在 Visual Studio 中通过 C# (Selenium) 自动登录 Gmail
EmailBackend 用于在 Django 中通过多个 SMTP 发送电子邮件
为啥编码标头内容类型:text/html;在 Outlook 插件中使用 MailItem 时缺少 GMAIL 的 SMTP 服务器:SMTP.GMAIL.COM?