最近学习了一下javax.mail,想通过gmail邮箱发送邮件到qq邮箱。但是由于gmail的两步验证,一直授权无法通过。
错误如下:
DEBUG: JavaMail version 1.4.7
DEBUG: successfully loaded resource: /META-INF/javamail.default.providers
DEBUG: Tables of loaded providers
DEBUG: Providers Listed By Class Name: {com.sun.mail.smtp.SMTPSSLTransport=javax.mail.Provider[TRANSPORT,smtps,com.sun.mail.smtp.SMTPSSLTransport,Oracle], com.sun.mail.smtp.SMTPTransport=javax.mail.Provider[TRANSPORT,smtp,com.sun.mail.smtp.SMTPTransport,Oracle], com.sun.mail.imap.IMAPSSLStore=javax.mail.Provider[STORE,imaps,com.sun.mail.imap.IMAPSSLStore,Oracle], com.sun.mail.pop3.POP3SSLStore=javax.mail.Provider[STORE,pop3s,com.sun.mail.pop3.POP3SSLStore,Oracle], com.sun.mail.imap.IMAPStore=javax.mail.Provider[STORE,imap,com.sun.mail.imap.IMAPStore,Oracle], com.sun.mail.pop3.POP3Store=javax.mail.Provider[STORE,pop3,com.sun.mail.pop3.POP3Store,Oracle]}
DEBUG: Providers Listed By Protocol: {imaps=javax.mail.Provider[STORE,imaps,com.sun.mail.imap.IMAPSSLStore,Oracle], imap=javax.mail.Provider[STORE,imap,com.sun.mail.imap.IMAPStore,Oracle], smtps=javax.mail.Provider[TRANSPORT,smtps,com.sun.mail.smtp.SMTPSSLTransport,Oracle], pop3=javax.mail.Provider[STORE,pop3,com.sun.mail.pop3.POP3Store,Oracle], pop3s=javax.mail.Provider[STORE,pop3s,com.sun.mail.pop3.POP3SSLStore,Oracle], smtp=javax.mail.Provider[TRANSPORT,smtp,com.sun.mail.smtp.SMTPTransport,Oracle]}
DEBUG: successfully loaded resource: /META-INF/javamail.default.address.map
DEBUG: getProvider() returning javax.mail.Provider[TRANSPORT,smtp,com.sun.mail.smtp.SMTPTransport,Oracle]
DEBUG SMTP: useEhlo true, useAuth true
DEBUG SMTP: useEhlo true, useAuth true
DEBUG SMTP: trying to connect to host "smtp.gmail.com", port 465, isSSL true
220 smtp.gmail.com ESMTP b14sm15106866pfc.76 - gsmtp
DEBUG SMTP: connected to host "smtp.gmail.com", port: 465
EHLO localhost.localdomain
250-smtp.gmail.com at your service
250-SIZE 35882577
250-8BITMIME
250-AUTH LOGIN PLAIN XOAUTH2 PLAIN-CLIENTTOKEN OAUTHBEARER XOAUTH
250-ENHANCEDSTATUSCODES
250-PIPELINING
250-CHUNKING
250 SMTPUTF8
DEBUG SMTP: Found extension "SIZE", arg "35882577"
DEBUG SMTP: Found extension "8BITMIME", arg ""
DEBUG SMTP: Found extension "AUTH", arg "LOGIN PLAIN XOAUTH2 PLAIN-CLIENTTOKEN OAUTHBEARER XOAUTH"
DEBUG SMTP: Found extension "ENHANCEDSTATUSCODES", arg ""
DEBUG SMTP: Found extension "PIPELINING", arg ""
DEBUG SMTP: Found extension "CHUNKING", arg ""
DEBUG SMTP: Found extension "SMTPUTF8", arg ""
DEBUG SMTP: Attempt to authenticate using mechanisms: LOGIN PLAIN DIGEST-MD5 NTLM
DEBUG SMTP: AUTH LOGIN command trace suppressed
DEBUG SMTP: AUTH LOGIN failed
javax.mail.AuthenticationFailedException: 534-5.7.14 <https://accounts.google.com/signin/continue?sarp=1&scc=1&plt=AKgnsbvN
534-5.7.14 -Ydbfzz5_p8nkoM2DkcL3JE5zXXPMGYitc88ssddwt_We6yYvnEq3SNDNu2bluXiiJ7P6L
534-5.7.14 hQMPHIvOpQ7DW8lnRUdv7FRrS_ZSP8HoQH1DNcNYMYhMkptySQeGO7UiZMR3tkRJzuPYnK
534-5.7.14 TRorlUpJQ-atwOtgez10BgedOHo4sYQkV6rLVNu7HG23YpUpJJLvhjw55q3phkBp0qcjja
534-5.7.14 2FsZf5BNQMRCBBlJOjyCqJAIJsnyQ> Please log in via your web browser and
534-5.7.14 then try again.
534-5.7.14 Learn more at
534 5.7.14 https://support.google.com/mail/answer/78754 b14sm15106866pfc.76 - gsmtp
at com.sun.mail.smtp.SMTPTransport$Authenticator.authenticate(SMTPTransport.java:826)
at com.sun.mail.smtp.SMTPTransport.authenticate(SMTPTransport.java:761)
at com.sun.mail.smtp.SMTPTransport.protocolConnect(SMTPTransport.java:685)
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 com.ecnu.mail.JavaMailDemo.gmailSender(JavaMailDemo.java:60)
at com.ecnu.mail.JavaMailDemo.main(JavaMailDemo.java:24)
通过查看gmail邮箱帮助:https://support.google.com/accounts/answer/6010255?authuser=1,需要开启“允许不够安全的应用”
开启后,可以通过gmail邮箱发送邮件到qq邮箱。
下面代码里分别测试了从gmai邮箱和qq邮箱发送邮件。但是通过qq邮箱发送邮件,需要使用qq邮箱的授权码,而gmail要开启“允许不够安全的应用”:
代码l如下:
package com.ecnu.mail;
import java.security.GeneralSecurityException;
import java.security.Security;
import java.util.Date;
import java.util.Properties;
import javax.mail.Authenticator;
import javax.mail.Message;
import javax.mail.Message.RecipientType;
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;
import com.sun.mail.util.MailSSLSocketFactory;
public class JavaMailDemo {
public static void main(String[] args) {
// qqSender();
gmailSender();
}
//gmail邮箱SSL方式
private static void gmailssl(Properties props) {
final String SSL_FACTORY = "javax.net.ssl.SSLSocketFactory";
props.put("mail.debug", "true");
props.put("mail.smtp.host", "smtp.gmail.com");
props.put("mail.smtp.ssl.enable", "true");
props.put("mail.smtp.socketFactory.class", SSL_FACTORY);
props.put("mail.smtp.port", "465");
props.put("mail.smtp.socketFactory.port", "465");
// props.put("mail.smtp.socketFactory.fallback", "false");
props.put("mail.smtp.auth", "true");
}
//gmail邮箱的TLS方式
private static void gmailtls(Properties props) {
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", "587");
}
/*
* 通过gmail邮箱发送邮件
*/
public static void gmailSender() {
// Get a Properties object
Properties props = new Properties();
//选择ssl方式
gmailssl(props);
final String username = "from@gmail.com";
final String password = "password";
Session session = Session.getDefaultInstance(props,
new Authenticator() {
protected PasswordAuthentication getPasswordAuthentication() {
return new PasswordAuthentication(username, password);
}
});
// -- Create a new message --
Message msg = new MimeMessage(session);
// -- Set the FROM and TO fields --
try {
msg.setFrom(new InternetAddress(username));
msg.setRecipients(Message.RecipientType.TO,
InternetAddress.parse("to@qq.com"));
msg.setSubject("Hello");
msg.setText("How are you");
msg.setSentDate(new Date());
Transport.send(msg);
} catch (AddressException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (MessagingException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
System.out.println("Message sent.");
}
/*
* 通过qq邮箱发送邮件,qq邮箱需要在设置里开启POP3/SMTP的授权,通过用户名+授权码方式才能发邮件
*/
public static void qqSender() {
MailSSLSocketFactory msf = null;
try {
msf = new MailSSLSocketFactory();
msf.setTrustAllHosts(true);
} catch (GeneralSecurityException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
Properties props = new Properties();
// 开启调试
props.setProperty("mail.debug", "true");
// 是否需要验证
props.setProperty("mail.smtp.auth", "true");
// 发送邮件服务器
props.setProperty("mail.smtp.host", "smtp.qq.com");
// 发送邮件协议名称
props.setProperty("mail.transport.protocol", "smtp");
props.put("mail.smtp.ssl.enable", "true");
props.put("mail.smtp.ssl.socketFactory", msf);
// 使用匿名内部类,用邮箱进行验证
Session session = Session.getInstance(props, new Authenticator() {
@Override
protected PasswordAuthentication getPasswordAuthentication() {
// 通过用户名和密码进行验证
return new PasswordAuthentication("from@qq.com",
"qq邮箱生成的授权码authcode");
}
});
Message message = new MimeMessage(session);
try {
// 设置邮件发送方
message.setFrom(new InternetAddress("from@qq.com"));
// 设置邮件标题
message.setSubject("测试");
// 设置邮件内容
message.setContent("测试", "text/html;charset=utf-8");
// 设置邮件接收方
message.addRecipient(RecipientType.TO, new InternetAddress(
"to@gmail.com"));
// 发送邮件
Transport.send(message);
} catch (AddressException e) {
e.printStackTrace();
} catch (MessagingException e) {
e.printStackTrace();
}
}
}