JavaMail (Jakarta Mail) для Java: полное руководство с примерами

Онлайн-тренажер Python для начинающих

Изучайте Python легко и без перегрузки теорией. Решайте практические задачи с автоматической проверкой, получайте подсказки на русском языке и пишите код прямо в браузере — без необходимости что-либо устанавливать.

Начать курс

JavaMail (Jakarta Mail) для Java: полное руководство с примерами

JavaMail (сейчас Jakarta Mail) — это стандартная библиотека Java для отправки, получения и обработки электронной почты. Она предоставляет мощный и гибкий API для работы с протоколами SMTP, POP3 и IMAP, позволяя разработчикам интегрировать почтовые функции в свои приложения. Библиотека является частью платформы Jakarta EE (ранее Java EE) и активно поддерживается сообществом Eclipse Foundation.

Зачем нужна JavaMail? В современной разработке практически любое корпоративное приложение требует отправки уведомлений, подтверждений регистрации, сброса паролей или рассылки отчетов. JavaMail позволяет делать это программно, без необходимости использовать сторонние сервисы или ручные операции. Библиотека поддерживает MIME-типы, вложения, HTML-письма, многопоточную отправку и шифрование (SSL/TLS).

Основные возможности включают: отправку писем через SMTP-сервер (Gmail, Yandex, собственный сервер), чтение почты через POP3/IMAP, работу с вложениями (изображения, PDF, архивы), поддержку multipart-сообщений, управление флагами (прочитано, удалено) и полную настройку соединения через Properties.

Установка

JavaMail (Jakarta Mail) распространяется через Maven Central. Для использования добавьте зависимость в ваш pom.xml (Maven) или build.gradle (Gradle).

Maven

<dependency>
    <groupId>com.sun.mail</groupId>
    <artifactId>javax.mail</artifactId>
    <version>1.6.2</version>
</dependency>

Для Jakarta Mail (новая версия, начиная с Jakarta EE 9):

<dependency>
    <groupId>com.sun.mail</groupId>
    <artifactId>jakarta.mail</artifactId>
    <version>2.0.1</version>
</dependency>

Gradle

implementation 'com.sun.mail:javax.mail:1.6.2'
// Или для Jakarta Mail:
implementation 'com.sun.mail:jakarta.mail:2.0.1'

Если вы используете Java 9+ и модульную систему, добавьте в module-info.java:

requires java.mail;

Быстрый старт — минимальный рабочий пример

Отправка простого текстового письма через SMTP-сервер Gmail (требуется включить "Доступ к менее безопасным приложениям" или использовать пароль приложения).

import java.util.Properties;
import javax.mail.*;
import javax.mail.internet.*;

public class QuickStart {
    public static void main(String[] args) {
        // Настройки SMTP
        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");

        // Аутентификация
        Session session = Session.getInstance(props, new Authenticator() {
            @Override
            protected PasswordAuthentication getPasswordAuthentication() {
                return new PasswordAuthentication("your-email@gmail.com", "your-password");
            }
        });

        try {
            // Создание письма
            Message message = new MimeMessage(session);
            message.setFrom(new InternetAddress("your-email@gmail.com"));
            message.setRecipients(Message.RecipientType.TO, InternetAddress.parse("recipient@example.com"));
            message.setSubject("Тестовое письмо из Java");
            message.setText("Привет! Это тестовое сообщение.");

            // Отправка
            Transport.send(message);
            System.out.println("Письмо отправлено успешно!");

        } catch (MessagingException e) {
            e.printStackTrace();
        }
    }
}

Основные методы/функции/классы

1. Session.getInstance(Properties, Authenticator)

Сигнатура: public static Session getInstance(Properties props, Authenticator authenticator)

Что делает: Создает сессию для работы с почтовым сервером. Сессия хранит настройки подключения и аутентификации.

Properties props = new Properties();
props.put("mail.smtp.host", "smtp.gmail.com");
props.put("mail.smtp.port", "587");
props.put("mail.smtp.auth", "true");

Session session = Session.getInstance(props, new Authenticator() {
    protected PasswordAuthentication getPasswordAuthentication() {
        return new PasswordAuthentication("user@gmail.com", "password");
    }
});

2. MimeMessage(Session)

Сигнатура: public MimeMessage(Session session)

Что делает: Создает новое MIME-сообщение для отправки. Позволяет задавать тему, получателей, содержимое и вложения.

MimeMessage message = new MimeMessage(session);
message.setSubject("Важное уведомление");
message.setFrom(new InternetAddress("from@example.com"));
message.setRecipient(Message.RecipientType.TO, new InternetAddress("to@example.com"));
message.setText("Текст письма");

3. InternetAddress(String)

Сигнатура: public InternetAddress(String address) throws AddressException

Что делает: Представляет email-адрес. Используется для задания отправителя, получателей и CC/BCC.

InternetAddress from = new InternetAddress("sender@example.com");
InternetAddress to = new InternetAddress("recipient@example.com");
InternetAddress[] cc = InternetAddress.parse("cc1@example.com, cc2@example.com");

4. Transport.send(Message)

Сигнатура: public static void send(Message msg) throws MessagingException

Что делает: Отправляет готовое сообщение через SMTP-сервер. Может выбрасывать исключения при проблемах с соединением или аутентификацией.

try {
    Transport.send(message);
    System.out.println("Письмо отправлено!");
} catch (MessagingException e) {
    System.err.println("Ошибка отправки: " + e.getMessage());
}

5. MimeBodyPart

Сигнатура: public MimeBodyPart()

Что делает: Представляет часть MIME-сообщения (текст, вложение, изображение). Используется для создания multipart-сообщений.

MimeBodyPart textPart = new MimeBodyPart();
textPart.setText("Текст письма");

MimeBodyPart attachmentPart = new MimeBodyPart();
attachmentPart.attachFile(new File("document.pdf"));
attachmentPart.setFileName("document.pdf");

6. Multipart

Сигнатура: public Multipart() (обычно используется MimeMultipart)

Что делает: Контейнер для нескольких MIME-частей. Позволяет комбинировать текст, HTML и вложения в одном письме.

MimeMultipart multipart = new MimeMultipart();
multipart.addBodyPart(textPart);
multipart.addBodyPart(attachmentPart);
message.setContent(multipart);

7. Store.connect(String host, String user, String password)

Сигнатура: public void connect(String host, int port, String user, String password) throws MessagingException

Что делает: Подключается к POP3/IMAP серверу для чтения почты. Требуется для получения писем.

Store store = session.getStore("imaps");
store.connect("imap.gmail.com", 993, "user@gmail.com", "password");
Folder inbox = store.getFolder("INBOX");
inbox.open(Folder.READ_ONLY);

8. Folder.getMessages()

Сигнатура: public Message[] getMessages() throws MessagingException

Что делает: Возвращает массив всех сообщений в папке. Можно фильтровать по флагам или дате.

Message[] messages = inbox.getMessages();
for (Message msg : messages) {
    System.out.println("Тема: " + msg.getSubject());
    System.out.println("От: " + msg.getFrom()[0]);
    System.out.println("Дата: " + msg.getSentDate());
    System.out.println("Текст: " + msg.getContent().toString());
}

9. Flags

Сигнатура: public Flags()

Что делает: Управляет флагами сообщений (прочитано, удалено, отвечено). Позволяет отмечать письма.

message.setFlag(Flags.Flag.SEEN, true);  // Отметить как прочитанное
message.setFlag(Flags.Flag.DELETED, true); // Пометить на удаление
inbox.expunge(); // Удалить помеченные сообщения

10. MimeMessage.setContent(Object, String)

Сигнатура: public void setContent(Object o, String type) throws MessagingException

Что делает: Устанавливает содержимое сообщения с указанием MIME-типа. Позволяет отправлять HTML-письма.

String html = "<h1>Привет!</h1><p>Это <b>HTML</b> письмо.</p>";
message.setContent(html, "text/html; charset=utf-8");

Реальный практический пример (150+ строк кода)

Пример полноценного почтового клиента: отправка письма с HTML-содержимым, вложением и изображением, встроенным в тело письма.

import javax.mail.*;
import javax.mail.internet.*;
import java.util.Properties;
import java.io.File;
import java.io.IOException;

public class EmailSender {
    private final String username;
    private final String password;
    private final String host;
    private final int port;
    private final boolean useTls;

    public EmailSender(String username, String password, String host, int port, boolean useTls) {
        this.username = username;
        this.password = password;
        this.host = host;
        this.port = port;
        this.useTls = useTls;
    }

    public void sendHtmlWithAttachment(String to, String subject, String htmlBody, 
                                       File attachment, File inlineImage) 
            throws MessagingException, IOException {
        
        // 1. Настройка свойств
        Properties props = new Properties();
        props.put("mail.smtp.host", host);
        props.put("mail.smtp.port", port);
        props.put("mail.smtp.auth", "true");
        if (useTls) {
            props.put("mail.smtp.starttls.enable", "true");
        }
        props.put("mail.smtp.ssl.protocols", "TLSv1.2");

        // 2. Создание сессии
        Session session = Session.getInstance(props, new Authenticator() {
            @Override
            protected PasswordAuthentication getPasswordAuthentication() {
                return new PasswordAuthentication(username, password);
            }
        });
        session.setDebug(true); // Включаем отладку

        // 3. Создание сообщения
        MimeMessage message = new MimeMessage(session);
        message.setFrom(new InternetAddress(username));
        message.setRecipients(Message.RecipientType.TO, InternetAddress.parse(to));
        message.setSubject(subject, "UTF-8");

        // 4. Создание multipart контейнера
        MimeMultipart multipart = new MimeMultipart("related");

        // 5. HTML часть
        MimeBodyPart htmlPart = new MimeBodyPart();
        htmlPart.setContent(htmlBody, "text/html; charset=utf-8");
        multipart.addBodyPart(htmlPart);

        // 6. Встроенное изображение (если есть)
        if (inlineImage != null && inlineImage.exists()) {
            MimeBodyPart imagePart = new MimeBodyPart();
            imagePart.attachFile(inlineImage);
            imagePart.setContentID("<image1>");
            imagePart.setDisposition(MimeBodyPart.INLINE);
            multipart.addBodyPart(imagePart);
        }

        // 7. Вложение (если есть)
        if (attachment != null && attachment.exists()) {
            MimeBodyPart attachmentPart = new MimeBodyPart();
            attachmentPart.attachFile(attachment);
            attachmentPart.setFileName(MimeUtility.encodeText(attachment.getName(), "UTF-8", null));
            multipart.addBodyPart(attachmentPart);
        }

        // 8. Устанавливаем содержимое
        message.setContent(multipart);
        message.saveChanges();

        // 9. Отправка
        Transport.send(message);
        System.out.println("Письмо успешно отправлено на " + to);
    }

    public static void main(String[] args) {
        // Настройки для Gmail (используйте пароль приложения!)
        EmailSender sender = new EmailSender(
            "your-email@gmail.com",
            "your-app-password",
            "smtp.gmail.com",
            587,
            true
        );

        try {
            String html = "<html><body>"
                + "<h1>Отчет за месяц</h1>"
                + "<p>Уважаемый пользователь, ваш отчет готов.</p>"
                + "<img src='cid:image1' alt='График' width='600'/>"
                + "<p>С уважением, команда поддержки.</p>"
                + "</body></html>";

            sender.sendHtmlWithAttachment(
                "recipient@example.com",
                "Ежемесячный отчет",
                html,
                new File("report.pdf"),
                new File("chart.png")
            );

        } catch (Exception e) {
            System.err.println("Ошибка: " + e.getMessage());
            e.printStackTrace();
        }
    }
}

Советы по производительности и типичные ошибки

Типичные ошибки

Рекомендаций