As title says, I would like to send emails with my gmail account writing some java code.
I have found many code examples, but none of them is working for me
正如标题所说,我想用我的Gmail帐户发送电子邮件,编写一些Java代码。我找到了许多代码示例,但没有一个对我有效
I was looking a this one: How can I send an email by Java application using GMail, Yahoo, or Hotmail?
我一直在寻找这个:我如何使用Gmail,Yahoo或Hotmail通过Java应用程序发送电子邮件?
I have tried the code posted as answer, but I get this exception:
我尝试了作为答案发布的代码,但得到以下异常:
javax.mail.MessagingException: Can't send command to SMTP host;
nested exception is:
javax.net.ssl.SSLHandshakeException: No appropriate protocol (protocol is disabled or cipher suites are inappropriate)
at com.sun.mail.smtp.SMTPTransport.sendCommand(SMTPTransport.java:1717)
at com.sun.mail.smtp.SMTPTransport.sendCommand(SMTPTransport.java:1704)
at com.sun.mail.smtp.SMTPTransport.ehlo(SMTPTransport.java:1088)
at com.sun.mail.smtp.SMTPTransport.protocolConnect(SMTPTransport.java:468)
at javax.mail.Service.connect(Service.java:291)
at javax.mail.Service.connect(Service.java:172)
...
The code is this:
代码如下:
public class GmailTest {
private static String USER_NAME = "*****"; // GMail user name (just the part before "@gmail.com")
private static String PASSWORD = "********"; // GMail password
private static String RECIPIENT = "[email protected]";
public static void main(String[] args) {
String from = USER_NAME;
String pass = PASSWORD;
String[] to = { RECIPIENT }; // list of recipient email addresses
String subject = "Java send mail example";
String body = "Welcome to JavaMail!";
sendFromGMail(from, pass, to, subject, body);
}
private static void sendFromGMail(String from, String pass, String[] to, String subject, String body) {
Properties props = System.getProperties();
String host = "smtp.gmail.com";
props.put("mail.smtp.starttls.enable", "true");
props.put("mail.smtp.host", host);
props.put("mail.smtp.user", from);
props.put("mail.smtp.password", pass);
props.put("mail.smtp.port", "587");
props.put("mail.smtp.auth", "true");
Session session = Session.getDefaultInstance(props);
MimeMessage message = new MimeMessage(session);
try {
message.setFrom(new InternetAddress(from));
InternetAddress[] toAddress = new InternetAddress[to.length];
// To get the array of addresses
for( int i = 0; i < to.length; i++ ) {
toAddress[i] = new InternetAddress(to[i]);
}
for( int i = 0; i < toAddress.length; i++) {
message.addRecipient(Message.RecipientType.TO, toAddress[i]);
}
message.setSubject(subject);
message.setText(body);
Transport transport = session.getTransport("smtp");
transport.connect(host, from, pass);
transport.sendMessage(message, message.getAllRecipients());
transport.close();
} catch (Exception e) {
e.printStackTrace();
}
}
}
Should this work in 2022 or did something change?
Why am I getting that exception?
这在2022年应该奏效吗?还是会有什么变化?为什么我会有这样的例外?
更多回答
what happens if you remove props.put("mail.smtp.auth", "true");
如果删除pros.put(“mail.smtp.auth”,“true”),会发生什么情况;
@DaImTo nothing changes, same error as before
@DaImTo没有任何变化,与之前相同的错误
public class EmailService {
private String username;
private String password;
private final Properties prop;
public EmailService(String host, int port, String username, String password) {
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", port);
prop.put("mail.smtp.ssl.trust", host);
this.username = username;
this.password = password;
}
public void sendMail(String from,String to,String subject, String msg) throws Exception {
Session session = Session.getInstance(prop, new Authenticator() {
@Override
protected PasswordAuthentication getPasswordAuthentication() {
return new PasswordAuthentication(username, password);
}
});
Message message = new MimeMessage(session);
message.setFrom(new InternetAddress(from));
message.setRecipients(Message.RecipientType.TO, InternetAddress.parse(to));
message.setSubject(subject);
MimeBodyPart mimeBodyPart = new MimeBodyPart();
mimeBodyPart.setContent(msg, "text/html; charset=utf-8");
Multipart multipart = new MimeMultipart();
multipart.addBodyPart(mimeBodyPart);
message.setContent(multipart);
Transport.send(message);
}
}
and then call the function like so:
然后按如下方式调用该函数:
new EmailService("smtp.gmail.com", 587, "<emailID>", "<pass(not the actual gmail-account password if you're using gmail for this>")
.sendMail("<emailID>",
toemail,
"<title>",
"<body>);
However, that's only half the solution. Since they discontinued the Less Secure App Access
feature on gmail accounts, you should access your gmail account through a different way now.
然而,这只是解决方案的一半。由于他们停止了Gmail账户上不太安全的App访问功能,你现在应该通过另一种方式访问你的Gmail账户。
You must enable 2FA on that gmail account, and add an entry to App passwords
under your google account. After that, the password you provide in the above function would be the 'App password' that you got from the gmail account(not the actual gmail account password, this one is auto-generated I believe).
你必须在该Gmail账户上启用2FA,并在你的谷歌账户下的App密码中添加一个条目。在那之后,你在上面的函数中提供的密码将是你从Gmail账户获得的‘App Password’(不是实际的Gmail账户密码,我相信这个密码是自动生成的)。
I am unaware of any other email service that offers smtp email feature for free nowadays. They all require you to pay in someway,except for gmail(Correct me if I'm wrong)
据我所知,目前还没有其他电子邮件服务提供免费的SMTP电子邮件功能。它们都要求你以某种方式付款,除了Gmail(如果我错了,请纠正我)
I figured this out a while back and this should work:
我很久以前就想到了这一点,这应该会奏效:
import javax.mail.*;
public class Emailer {
private final String username;
private final String password;
private Session session;
public Emailer(String username, String password) {
this.username = username;
this.password = password;
}
public void send(String email, String subject, String content) {
if (hasSession()) {
try {
Transport.send(createMimeMessage(email, session, subject, content));
System.out.printf("Email sent to %s%n", email);
} catch (MessagingException e) {
e.printStackTrace();
}
}
}
private boolean hasSession() {
if (session == null) {
session = startSessionTLS();
}
if (session == null) {
System.out.printf("Cannot start email session%n");
return false;
}
return true;
}
private Session startSessionTLS() {
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.starttls.enable", "true");
return Session.getInstance(props, new javax.mail.Authenticator() {
protected PasswordAuthentication getPasswordAuthentication() {
return new PasswordAuthentication(username, password);
}
});
}
private MimeMessage createMimeMessage(String email, Session session, String subject, String body) throws MessagingException {
MimeMessage message = new MimeMessage(session);
message.setFrom(new InternetAddress("[email protected]"));
message.setRecipients(Message.RecipientType.TO, InternetAddress.parse(email));
message.setSubject(subject);
message.setText(body);
return message;
}
}
First of all, you cannot use password while sending email via Gmail. You need to generate app-specific password for this.
首先,通过Gmail发送电子邮件时不能使用密码。您需要为此生成特定于应用程序的密码。
To enable app-specific password follow below steps.
要启用特定于应用程序的密码,请执行以下步骤。
Step 1: Enable 2FA. To enable 2FA, please click here.
步骤1:启用2FA。要启用2FA,请单击此处。
Step 2: Create an app-specific password. To create one, please click here.
步骤2:创建特定于应用程序的密码。要创建一个,请单击此处。
Click on the highlighted option from the "Select app" dropdown. Click Generate. It will generate 16 digits password and appear only once. Copy somewhere for future use.
点击“选择应用”下拉列表中突出显示的选项。单击生成。它将生成16位数字的密码,并且只出现一次。复制到某个地方以备将来使用。
In application.properties file add below lines for email configurations
在application.properties文件中添加以下行用于电子邮件配置
spring.mail.host=smtp.gmail.com
spring.mail.port=587
spring.mail.username=YOUR GMAIL ID
spring.mail.password=APP-SPECIFIC PASSWORD
spring.mail.properties.mail.smtp.auth=true
spring.mail.properties.mail.smtp.starttls.enable=true
The maven dependency can also be added by modifying your project’s pom.xml file to include the following
还可以通过修改项目的pom.xml文件来添加maven依赖项,使其包含以下内容
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-mail</artifactId>
</dependency>
If you need HTML email, you can use MimeMessage
class for this purpose.
如果您需要HTML电子邮件,您可以使用MimeMessage类来实现此目的。
The service file to send the email is as following. This will create HTML emails for you.
发送电子邮件的服务文件如下所示。这将为您创建超文本标记语言电子邮件。
package com.comp.service;
import javax.mail.MessagingException;
import javax.mail.internet.MimeMessage;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.mail.javamail.JavaMailSender;
import org.springframework.stereotype.Service;
import com.comp.serviceIntf.EmailService;
@Service
public class EmailServiceImpl implements EmailService {
@Autowired
private JavaMailSender mailSender;
@Override
public void sendEmail(String to, String name, String userid, String password) throws MessagingException
{
String htmlContent = "Hi %s, <br /><br />Welcome to <b>MyCompany</b>. <br />Your UserID is: <b>%s</b> and Password is: <b>%s</b><br /><h5>This is system generated password. You can change it anytime after login.</h5><h5>Please do not share this credential with anybody else.</h5><br />With regards,<br />MyCompany";
htmlContent = String.format(htmlContent, name, userid, password);
String subject = "Welcome %s (%s) on successful registration";
subject = String.format(subject, name, userid);
MimeMessage message = mailSender.createMimeMessage();
message.setRecipients(MimeMessage.RecipientType.TO, to);
message.setSubject(subject);
message.setContent(htmlContent, "text/html; charset=utf-8");
mailSender.send(message);
}
}
If you do not need HTML email, you can use SimpleMailMessage
class for this purpose.
如果您不需要HTML电子邮件,则可以使用SimpleMailMessage类来实现此目的。
SimpleMailMessage message = new SimpleMailMessage();
message.setTo(to);
message.setSubject(subject);
message.setText(body);
mailSender.send(message);
Note: I am unaware of any other email like yahoo, outlook etc. This discussion is purely from Gmail point of view.
注:我不知道有任何其他电子邮件,如雅虎,Outlook等。这是纯粹从Gmail的角度讨论。
更多回答
Ok I have enabled the 2FA on the gmail account, and created an app password (for a Windows Computer). Now when i try to run your code, at the line Transport.send(message); i get the following exception: javax.mail.MessagingException: Can't send command to SMTP host; nested exception is: javax.net.ssl.SSLHandshakeException: No appropriate protocol (protocol is disabled or cipher suites are inappropriate)
好了,我已经在Gmail帐户上启用了2FA,并创建了一个应用程序密码(用于Windows计算机)。现在,当我尝试运行您的代码时,在Transport.end(Message)行;我得到以下异常:javax.mail.MessagingException:无法向SMTP主机发送命令;嵌套异常是:javax.net.ssl.SSLHandshakeException:没有合适的协议(协议被禁用或密码套件不合适)
@Maik Try to first send the email through curl, if it works through curl, then the issue is definitely either jdk version or the email library version related. If it doesn't work through curl, then the issue is probably incorrect authentication
@Maik尝试首先通过cURL发送电子邮件,如果它通过cURL工作,那么问题肯定是与JDK版本或电子邮件库版本相关的。如果它不能通过cURL工作,那么问题可能是不正确的身份验证
@Maik Here is a simple one line command to send email through curl
@Maik这里是一个通过curl发送电子邮件的简单的一行命令
I didn't know what curl is, I'm learning... The example you linked is for linux, but I guess it should work on a windows machine too, right? I get this error: "curl: (3) URL using bad/illegal format or missing URL". The right port to use is 465 or 587?
我不知道卷发是什么,我正在学习...你链接的例子是针对Linux的,但我想它应该也能在Windows机器上运行,对吧?我收到这个错误:“cURL:(3)URL使用了错误/非法的格式或缺少URL”。正确的端口是465还是587?
@Maik , just remove the backslashes, and it should work. The backslashes are used for spanning the command across multiple lines in a linux
terminal. The equivalent would be ^
in windows
在Windows中,等效项为^
我是一名优秀的程序员,十分优秀!