Автор оригинала: 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-программах.