Автор оригинала: Pankaj Kumar.
Сегодня мы рассмотрим пример JavaMail для отправки электронной почты в java-программах. Отправка электронной почты является одной из распространенных задач в реальных приложениях, и именно поэтому Java предоставляет надежный JavaMail API , который мы можем использовать для отправки электронной почты с помощью SMTP-сервера. JavaMail API поддерживает как TLS, так и SSL-аутентификацию для отправки электронной почты.
Пример JavaMail
Сегодня мы узнаем, как использовать JavaMail API для отправки электронных писем с помощью SMTP-сервера без аутентификации, аутентификации TLS и SSL, а также как отправлять вложения, прикреплять и использовать изображения в теле письма. Для проверки подлинности TLS и SSL я использую SMTP-сервер GMail, потому что он поддерживает их оба. Вы также можете выбрать почтовый сервер Java в зависимости от потребностей вашего проекта.
JavaMail API не является частью стандартного JDK, поэтому вам придется загрузить его с официального сайта, т. е. с домашней страницы JavaMail . Загрузите последнюю версию эталонной реализации JavaMail и включите ее в свой путь сборки проекта. Имя файла jar будет javax.mail.jar .
Если вы используете проект на основе Maven, просто добавьте нижеприведенную зависимость в свой проект.
com.sun.mail javax.mail 1.5.5
Программа Java для отправки электронной почты содержит следующие шаги:
- Создание
javax.mail.Сеансаобъекта - Создавая
javax.mail.internet.MimeMessageобъект, мы должны задать различные свойства в этом объекте, такие как адрес электронной почты получателя, Тема электронной почты, Ответ на электронное письмо, текст письма, вложения и т.д. - Использование
javax.mail.Транспортдля отправки сообщения электронной почты.
Логика создания сеанса отличается в зависимости от типа SMTP-сервера, например, если SMTP-сервер не требует аутентификации, мы можем создать объект сеанса с некоторыми простыми свойствами, тогда как если для него требуется аутентификация по протоколу TLS или SSL, логика создания будет отличаться.
Поэтому я создам служебный класс с некоторыми служебными методами для отправки электронных писем, а затем буду использовать этот служебный метод с различными SMTP-серверами.
Пример программы JavaMail
Наш класс EmailUtil, у которого есть один метод для отправки электронной почты, выглядит следующим образом, для него требуется javax.mail.Session и некоторые другие обязательные поля в качестве аргументов. Для простоты некоторые аргументы жестко закодированы, но вы можете расширить этот метод, чтобы передать их или прочитать из некоторых файлов конфигурации.
package com.journaldev.mail;
import java.io.UnsupportedEncodingException;
import java.util.Date;
import javax.activation.DataHandler;
import javax.activation.DataSource;
import javax.activation.FileDataSource;
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.InternetAddress;
import javax.mail.internet.MimeBodyPart;
import javax.mail.internet.MimeMessage;
import javax.mail.internet.MimeMultipart;
public class EmailUtil {
/**
* Utility method to send simple HTML email
* @param session
* @param toEmail
* @param subject
* @param body
*/
public static void sendEmail(Session session, String toEmail, String subject, String body){
try
{
MimeMessage msg = new MimeMessage(session);
//set message headers
msg.addHeader("Content-type", "text/HTML; charset=UTF-8");
msg.addHeader("format", "flowed");
msg.addHeader("Content-Transfer-Encoding", "8bit");
msg.setFrom(new InternetAddress("no_reply@example.com", "NoReply-JD"));
msg.setReplyTo(InternetAddress.parse("no_reply@example.com", false));
msg.setSubject(subject, "UTF-8");
msg.setText(body, "UTF-8");
msg.setSentDate(new Date());
msg.setRecipients(Message.RecipientType.TO, InternetAddress.parse(toEmail, false));
System.out.println("Message is ready");
Transport.send(msg);
System.out.println("EMail Sent Successfully!!");
}
catch (Exception e) {
e.printStackTrace();
}
}
}
Обратите внимание, что я устанавливаю некоторые свойства заголовка в MimeMessage, они используются почтовыми клиентами для правильной визуализации и отображения сообщения электронной почты. Остальная часть программы проста и понятна для самого себя.
Теперь давайте создадим нашу программу для отправки электронной почты без аутентификации.
Отправляйте почту на Java с помощью SMTP без аутентификации
package com.journaldev.mail;
import java.util.Properties;
import javax.mail.Session;
public class SimpleEmail {
public static void main(String[] args) {
System.out.println("SimpleEmail Start");
String smtpHostServer = "smtp.example.com";
String emailID = "email_me@example.com";
Properties props = System.getProperties();
props.put("mail.smtp.host", smtpHostServer);
Session session = Session.getInstance(props, null);
EmailUtil.sendEmail(session, emailID,"SimpleEmail Testing Subject", "SimpleEmail Testing Body");
}
}
Обратите внимание, что я использую Session.getInstance() для получения объекта сеанса путем передачи объекта Свойств. Нам нужно установить свойство mail.smtp.host с хостом SMTP-сервера. Если SMTP-сервер не работает на порту по умолчанию (25), вам также необходимо установить mail.smtp.port свойство. Просто запустите эту программу с вашего SMTP-сервера без аутентификации и, установив идентификатор электронной почты получателя в качестве своего собственного идентификатора электронной почты, и вы получите электронное письмо в кратчайшие сроки.
Программа проста для понимания и хорошо работает, но в реальной жизни большинство SMTP-серверов используют какую-либо аутентификацию, такую как аутентификация TLS или SSL. Итак, теперь мы увидим, как создать объект сеанса для этих протоколов аутентификации.
Отправка электронной почты в Java SMTP с проверкой подлинности TLS
package com.journaldev.mail;
import java.util.Properties;
import javax.mail.Authenticator;
import javax.mail.PasswordAuthentication;
import javax.mail.Session;
public class TLSEmail {
/**
Outgoing Mail (SMTP) Server
requires TLS or SSL: smtp.gmail.com (use authentication)
Use Authentication: Yes
Port for TLS/STARTTLS: 587
*/
public static void main(String[] args) {
final String fromEmail = "myemailid@gmail.com"; //requires valid gmail id
final String password = "mypassword"; // correct password for gmail id
final String toEmail = "myemail@yahoo.com"; // can be any email id
System.out.println("TLSEmail Start");
Properties props = new Properties();
props.put("mail.smtp.host", "smtp.gmail.com"); //SMTP Host
props.put("mail.smtp.port", "587"); //TLS Port
props.put("mail.smtp.auth", "true"); //enable authentication
props.put("mail.smtp.starttls.enable", "true"); //enable STARTTLS
//create Authenticator object to pass in Session.getInstance argument
Authenticator auth = new Authenticator() {
//override the getPasswordAuthentication method
protected PasswordAuthentication getPasswordAuthentication() {
return new PasswordAuthentication(fromEmail, password);
}
};
Session session = Session.getInstance(props, auth);
EmailUtil.sendEmail(session, toEmail,"TLSEmail Testing Subject", "TLSEmail Testing Body");
}
}
Поскольку я использую SMTP-сервер GMail, доступный для всех, вы можете установить правильные переменные в приведенной выше программе и запустить ее самостоятельно. Поверьте мне, это работает!! 🙂
Пример Java SMTP с проверкой подлинности SSL
package com.journaldev.mail;
import java.util.Properties;
import javax.mail.Authenticator;
import javax.mail.PasswordAuthentication;
import javax.mail.Session;
public class SSLEmail {
/**
Outgoing Mail (SMTP) Server
requires TLS or SSL: smtp.gmail.com (use authentication)
Use Authentication: Yes
Port for SSL: 465
*/
public static void main(String[] args) {
final String fromEmail = "myemailid@gmail.com"; //requires valid gmail id
final String password = "mypassword"; // correct password for gmail id
final String toEmail = "myemail@yahoo.com"; // can be any email id
System.out.println("SSLEmail Start");
Properties props = new Properties();
props.put("mail.smtp.host", "smtp.gmail.com"); //SMTP Host
props.put("mail.smtp.socketFactory.port", "465"); //SSL Port
props.put("mail.smtp.socketFactory.class",
"javax.net.ssl.SSLSocketFactory"); //SSL Factory Class
props.put("mail.smtp.auth", "true"); //Enabling SMTP Authentication
props.put("mail.smtp.port", "465"); //SMTP Port
Authenticator auth = new Authenticator() {
//override the getPasswordAuthentication method
protected PasswordAuthentication getPasswordAuthentication() {
return new PasswordAuthentication(fromEmail, password);
}
};
Session session = Session.getDefaultInstance(props, auth);
System.out.println("Session created");
EmailUtil.sendEmail(session, toEmail,"SSLEmail Testing Subject", "SSLEmail Testing Body");
EmailUtil.sendAttachmentEmail(session, toEmail,"SSLEmail Testing Subject with Attachment", "SSLEmail Testing Body with Attachment");
EmailUtil.sendImageEmail(session, toEmail,"SSLEmail Testing Subject with Image", "SSLEmail Testing Body with Image");
}
}
Программа почти такая же, как проверка подлинности TLS, только некоторые свойства отличаются. Как вы можете видеть, я вызываю некоторые другие методы из класса EmailUtil для отправки вложения и изображения по электронной почте, но я еще не определил их. На самом деле я сохранил их, чтобы показать позже и упростить в начале урока.
Пример JavaMail – отправка почты на java с вложением
Чтобы отправить файл в качестве вложения, нам нужно создать объект javax.mail.internet.MimeBodyPart и javax.mail.internet.MimeMultipart . Сначала добавьте основную часть текстового сообщения в электронное письмо, а затем используйте FileDataSource, чтобы прикрепить файл во второй части составного текста. Метод выглядит следующим образом.
/**
* Utility method to send email with attachment
* @param session
* @param toEmail
* @param subject
* @param body
*/
public static void sendAttachmentEmail(Session session, String toEmail, String subject, String body){
try{
MimeMessage msg = new MimeMessage(session);
msg.addHeader("Content-type", "text/HTML; charset=UTF-8");
msg.addHeader("format", "flowed");
msg.addHeader("Content-Transfer-Encoding", "8bit");
msg.setFrom(new InternetAddress("no_reply@example.com", "NoReply-JD"));
msg.setReplyTo(InternetAddress.parse("no_reply@example.com", false));
msg.setSubject(subject, "UTF-8");
msg.setSentDate(new Date());
msg.setRecipients(Message.RecipientType.TO, InternetAddress.parse(toEmail, false));
// Create the message body part
BodyPart messageBodyPart = new MimeBodyPart();
// Fill the message
messageBodyPart.setText(body);
// Create a multipart message for attachment
Multipart multipart = new MimeMultipart();
// Set text message part
multipart.addBodyPart(messageBodyPart);
// Second part is attachment
messageBodyPart = new MimeBodyPart();
String filename = "abc.txt";
DataSource source = new FileDataSource(filename);
messageBodyPart.setDataHandler(new DataHandler(source));
messageBodyPart.setFileName(filename);
multipart.addBodyPart(messageBodyPart);
// Send the complete message parts
msg.setContent(multipart);
// Send message
Transport.send(msg);
System.out.println("EMail Sent Successfully with attachment!!");
}catch (MessagingException e) {
e.printStackTrace();
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
}
На первый взгляд программа может показаться сложной, но она проста, просто создайте часть тела для текстового сообщения и другую часть тела для вложения, а затем добавьте их в составную часть. Вы также можете расширить этот метод, чтобы прикрепить несколько файлов.
Пример JavaMail – отправка почты на java с изображением
Поскольку мы можем создать текст сообщения в формате HTML, если файл изображения находится на каком-либо сервере, мы можем использовать элемент img , чтобы отобразить их в сообщении. Но иногда мы хотим прикрепить изображение в электронном письме, а затем использовать его в самом теле письма. Вы, должно быть, видели так много писем с вложениями изображений, которые также используются в сообщении электронной почты.
Хитрость заключается в том, чтобы прикрепить файл изображения, как и любое другое вложение, а затем установить заголовок Content-ID для файла изображения, а затем использовать тот же идентификатор содержимого в теле сообщения электронной почты с src='cid:image_id'> . src=’cid:image_id’>
/**
* Utility method to send image in email body
* @param session
* @param toEmail
* @param subject
* @param body
*/
public static void sendImageEmail(Session session, String toEmail, String subject, String body){
try{
MimeMessage msg = new MimeMessage(session);
msg.addHeader("Content-type", "text/HTML; charset=UTF-8");
msg.addHeader("format", "flowed");
msg.addHeader("Content-Transfer-Encoding", "8bit");
msg.setFrom(new InternetAddress("no_reply@example.com", "NoReply-JD"));
msg.setReplyTo(InternetAddress.parse("no_reply@example.com", false));
msg.setSubject(subject, "UTF-8");
msg.setSentDate(new Date());
msg.setRecipients(Message.RecipientType.TO, InternetAddress.parse(toEmail, false));
// Create the message body part
BodyPart messageBodyPart = new MimeBodyPart();
messageBodyPart.setText(body);
// Create a multipart message for attachment
Multipart multipart = new MimeMultipart();
// Set text message part
multipart.addBodyPart(messageBodyPart);
// Second part is image attachment
messageBodyPart = new MimeBodyPart();
String filename = "image.png";
DataSource source = new FileDataSource(filename);
messageBodyPart.setDataHandler(new DataHandler(source));
messageBodyPart.setFileName(filename);
//Trick is to add the content-id header here
messageBodyPart.setHeader("Content-ID", "image_id");
multipart.addBodyPart(messageBodyPart);
//third part for displaying image in the email body
messageBodyPart = new MimeBodyPart();
messageBodyPart.setContent("Attached Image
" +
"
", "text/html");
multipart.addBodyPart(messageBodyPart);
//Set the multipart message to the email message
msg.setContent(multipart);
// Send message
Transport.send(msg);
System.out.println("EMail Sent Successfully with image!!");
}catch (MessagingException e) {
e.printStackTrace();
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
}
Советы по устранению неполадок API JavaMail
java.net.Исключение UnknownHostExceptionвозникает, когда ваша система не может разрешить IP-адрес SMTP-сервера, он может быть неправильным или недоступен из вашей сети. Например, SMTP-сервер GMail является smtp.gmail.com и если я использую smtp.google.com, я получу это исключение. Если имя хоста указано правильно, попробуйте выполнить пинг сервера через командную строку, чтобы убедиться, что он доступен из вашей системы.- Если ваша программа застряла в вызове метода Transport send (), проверьте правильность порта SMTP. Если это правильно, то используйте telnet, чтобы убедиться, что он доступен с вашего компьютера, вы получите вывод, как показано ниже.
Это все для примера JavaMail для отправки почты на java с использованием SMTP – сервера с различными протоколами аутентификации, вложениями и изображениями. Я надеюсь, что это решит все ваши потребности в отправке электронных писем в java-программах.