Aşağıdaki kod, Google SMTP sunucusuyla çok iyi çalışır. Google kullanıcı adınızı ve şifrenizi sağlamanız gerekiyor.
import com.sun.mail.smtp.SMTPTransport;
import java.security.Security;
import java.util.Date;
import java.util.Properties;
import javax.mail.Message;
import javax.mail.MessagingException;
import javax.mail.Session;
import javax.mail.internet.AddressException;
import javax.mail.internet.InternetAddress;
import javax.mail.internet.MimeMessage;
/**
*
* @author doraemon
*/
public class GoogleMail {
private GoogleMail() {
}
/**
* Send email using GMail SMTP server.
*
* @param username GMail username
* @param password GMail password
* @param recipientEmail TO recipient
* @param title title of the message
* @param message message to be sent
* @throws AddressException if the email address parse failed
* @throws MessagingException if the connection is dead or not in the connected state or if the message is not a MimeMessage
*/
public static void Send(final String username, final String password, String recipientEmail, String title, String message) throws AddressException, MessagingException {
GoogleMail.Send(username, password, recipientEmail, "", title, message);
}
/**
* Send email using GMail SMTP server.
*
* @param username GMail username
* @param password GMail password
* @param recipientEmail TO recipient
* @param ccEmail CC recipient. Can be empty if there is no CC recipient
* @param title title of the message
* @param message message to be sent
* @throws AddressException if the email address parse failed
* @throws MessagingException if the connection is dead or not in the connected state or if the message is not a MimeMessage
*/
public static void Send(final String username, final String password, String recipientEmail, String ccEmail, String title, String message) throws AddressException, MessagingException {
Security.addProvider(new com.sun.net.ssl.internal.ssl.Provider());
final String SSL_FACTORY = "javax.net.ssl.SSLSocketFactory";
// Get a Properties object
Properties props = System.getProperties();
props.setProperty("mail.smtps.host", "smtp.gmail.com");
props.setProperty("mail.smtp.socketFactory.class", SSL_FACTORY);
props.setProperty("mail.smtp.socketFactory.fallback", "false");
props.setProperty("mail.smtp.port", "465");
props.setProperty("mail.smtp.socketFactory.port", "465");
props.setProperty("mail.smtps.auth", "true");
/*
If set to false, the QUIT command is sent and the connection is immediately closed. If set
to true (the default), causes the transport to wait for the response to the QUIT command.
ref : http://java.sun.com/products/javamail/javadocs/com/sun/mail/smtp/package-summary.html
http://forum.java.sun.com/thread.jspa?threadID=5205249
smtpsend.java - demo program from javamail
*/
props.put("mail.smtps.quitwait", "false");
Session session = Session.getInstance(props, null);
// -- Create a new message --
final MimeMessage msg = new MimeMessage(session);
// -- Set the FROM and TO fields --
msg.setFrom(new InternetAddress(username + "@gmail.com"));
msg.setRecipients(Message.RecipientType.TO, InternetAddress.parse(recipientEmail, false));
if (ccEmail.length() > 0) {
msg.setRecipients(Message.RecipientType.CC, InternetAddress.parse(ccEmail, false));
}
msg.setSubject(title);
msg.setText(message, "utf-8");
msg.setSentDate(new Date());
SMTPTransport t = (SMTPTransport)session.getTransport("smtps");
t.connect("smtp.gmail.com", username, password);
t.sendMessage(msg, msg.getAllRecipients());
t.close();
}
}
11 Aralık 2015 ile ilgili güncelleme
Kullanıcı adı + şifre artık önerilen bir çözüm değil. Bunun nedeni
Bunu denedim ve Gmail, bu kodda kullanıcı adı olarak kullanılan e-postayı, kısa süre önce Google Hesabınızda bir oturum açma girişimini engellediğimizi belirten bir e-posta gönderdi ve beni şu destek sayfasına yönlendirdi: support.google.com/accounts/answer/6010255 bu yüzden çalışıp çalışmadığını arar, göndermek için kullanılan e-posta hesabının kendi güvenliklerini
Google, Gmail API'yi yayınladı - https://developers.google.com/gmail/api/?hl=en . Kullanıcı adı + şifre yerine oAuth2 yöntemini kullanmalıyız.
İşte Gmail API ile çalışacak kod pasajı.
GoogleMail.java
import com.google.api.client.util.Base64;
import com.google.api.services.gmail.Gmail;
import com.google.api.services.gmail.model.Message;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.util.Properties;
import javax.mail.MessagingException;
import javax.mail.Session;
import javax.mail.internet.InternetAddress;
import javax.mail.internet.MimeMessage;
/**
*
* @author doraemon
*/
public class GoogleMail {
private GoogleMail() {
}
private static MimeMessage createEmail(String to, String cc, String from, String subject, String bodyText) throws MessagingException {
Properties props = new Properties();
Session session = Session.getDefaultInstance(props, null);
MimeMessage email = new MimeMessage(session);
InternetAddress tAddress = new InternetAddress(to);
InternetAddress cAddress = cc.isEmpty() ? null : new InternetAddress(cc);
InternetAddress fAddress = new InternetAddress(from);
email.setFrom(fAddress);
if (cAddress != null) {
email.addRecipient(javax.mail.Message.RecipientType.CC, cAddress);
}
email.addRecipient(javax.mail.Message.RecipientType.TO, tAddress);
email.setSubject(subject);
email.setText(bodyText);
return email;
}
private static Message createMessageWithEmail(MimeMessage email) throws MessagingException, IOException {
ByteArrayOutputStream baos = new ByteArrayOutputStream();
email.writeTo(baos);
String encodedEmail = Base64.encodeBase64URLSafeString(baos.toByteArray());
Message message = new Message();
message.setRaw(encodedEmail);
return message;
}
public static void Send(Gmail service, String recipientEmail, String ccEmail, String fromEmail, String title, String message) throws IOException, MessagingException {
Message m = createMessageWithEmail(createEmail(recipientEmail, ccEmail, fromEmail, title, message));
service.users().messages().send("me", m).execute();
}
}
OAuth2 aracılığıyla yetkili bir Gmail hizmeti oluşturmak için, işte kod pasajı.
Utils.java
import com.google.api.client.auth.oauth2.Credential;
import com.google.api.client.extensions.jetty.auth.oauth2.LocalServerReceiver;
import com.google.api.client.googleapis.auth.oauth2.GoogleAuthorizationCodeFlow;
import com.google.api.client.googleapis.auth.oauth2.GoogleClientSecrets;
import com.google.api.client.googleapis.javanet.GoogleNetHttpTransport;
import com.google.api.client.http.HttpTransport;
import com.google.api.client.json.gson.GsonFactory;
import com.google.api.client.util.store.FileDataStoreFactory;
import com.google.api.services.gmail.Gmail;
import com.google.api.services.gmail.GmailScopes;
import com.google.api.services.oauth2.Oauth2;
import com.google.api.services.oauth2.model.Userinfoplus;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.security.GeneralSecurityException;
import java.util.HashSet;
import java.util.Set;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.yccheok.jstock.engine.Pair;
/**
*
* @author yccheok
*/
public class Utils {
/** Global instance of the JSON factory. */
private static final GsonFactory JSON_FACTORY = GsonFactory.getDefaultInstance();
/** Global instance of the HTTP transport. */
private static HttpTransport httpTransport;
private static final Log log = LogFactory.getLog(Utils.class);
static {
try {
// initialize the transport
httpTransport = GoogleNetHttpTransport.newTrustedTransport();
} catch (IOException ex) {
log.error(null, ex);
} catch (GeneralSecurityException ex) {
log.error(null, ex);
}
}
private static File getGmailDataDirectory() {
return new File(org.yccheok.jstock.gui.Utils.getUserDataDirectory() + "authentication" + File.separator + "gmail");
}
/**
* Send a request to the UserInfo API to retrieve the user's information.
*
* @param credentials OAuth 2.0 credentials to authorize the request.
* @return User's information.
* @throws java.io.IOException
*/
public static Userinfoplus getUserInfo(Credential credentials) throws IOException
{
Oauth2 userInfoService =
new Oauth2.Builder(httpTransport, JSON_FACTORY, credentials).setApplicationName("JStock").build();
Userinfoplus userInfo = userInfoService.userinfo().get().execute();
return userInfo;
}
public static String loadEmail(File dataStoreDirectory) {
File file = new File(dataStoreDirectory, "email");
try {
return new String(Files.readAllBytes(Paths.get(file.toURI())), "UTF-8");
} catch (IOException ex) {
log.error(null, ex);
return null;
}
}
public static boolean saveEmail(File dataStoreDirectory, String email) {
File file = new File(dataStoreDirectory, "email");
try {
//If the constructor throws an exception, the finally block will NOT execute
BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(file), "UTF-8"));
try {
writer.write(email);
} finally {
writer.close();
}
return true;
} catch (IOException ex){
log.error(null, ex);
return false;
}
}
public static void logoutGmail() {
File credential = new File(getGmailDataDirectory(), "StoredCredential");
File email = new File(getGmailDataDirectory(), "email");
credential.delete();
email.delete();
}
public static Pair<Pair<Credential, String>, Boolean> authorizeGmail() throws Exception {
// Ask for only the permissions you need. Asking for more permissions will
// reduce the number of users who finish the process for giving you access
// to their accounts. It will also increase the amount of effort you will
// have to spend explaining to users what you are doing with their data.
// Here we are listing all of the available scopes. You should remove scopes
// that you are not actually using.
Set<String> scopes = new HashSet<>();
// We would like to display what email this credential associated to.
scopes.add("email");
scopes.add(GmailScopes.GMAIL_SEND);
// load client secrets
GoogleClientSecrets clientSecrets = GoogleClientSecrets.load(Utils.JSON_FACTORY,
new InputStreamReader(Utils.class.getResourceAsStream("/assets/authentication/gmail/client_secrets.json")));
return authorize(clientSecrets, scopes, getGmailDataDirectory());
}
/** Authorizes the installed application to access user's protected data.
* @return
* @throws java.lang.Exception */
private static Pair<Pair<Credential, String>, Boolean> authorize(GoogleClientSecrets clientSecrets, Set<String> scopes, File dataStoreDirectory) throws Exception {
// Set up authorization code flow.
GoogleAuthorizationCodeFlow flow = new GoogleAuthorizationCodeFlow.Builder(
httpTransport, JSON_FACTORY, clientSecrets, scopes)
.setDataStoreFactory(new FileDataStoreFactory(dataStoreDirectory))
.build();
// authorize
return new MyAuthorizationCodeInstalledApp(flow, new LocalServerReceiver()).authorize("user");
}
public static Gmail getGmail(Credential credential) {
Gmail service = new Gmail.Builder(httpTransport, JSON_FACTORY, credential).setApplicationName("JStock").build();
return service;
}
}
OAuth2 kimlik doğrulamasının kullanıcı dostu bir yolunu sağlamak için, aşağıdaki giriş iletişim kutusunu görüntülemek için JavaFX'i kullandım
Kullanıcı dostu oAuth2 iletişim kutusunu görüntüleme anahtarı MyAuthorizationCodeInstalledApp.java ve SimpleSwingBrowser.java'da bulunabilir.