25 февраля 2023
Тэги: gradle, Kotlin, Spring, Spring Boot, YouTube.
В этой статье вы узнаете, как отправлять email в Spring Boot. Также можно посмотреть исходники этого примера на github и видео на YouTube.
Для начала создадим новый gradle-проект. Проще всего это сделать с помощью Spring Initializr. Там выбираем параметры Java 17, язык – Kotlin, сборщик Gradle – Kotlin. В зависимости добавим Spring Web и Java Mail Sender. В итоге в проекте должно быть прописано:
Стартер spring-boot-starter-mail добавляет саму функциональность работы с email.
Теперь в папке resources переименуем файл application.properties в application.yml и добавим в него параметры подключения к почтовому ящику, через который будем отправлять письма:
Здесь я использую почтовый ящик Yandex. Мы указываем хост и порт mail-сервера, а также логин/пароль для доступа к нему. Параметр test-connection отвечает за проверку подключения к серверу при старте приложения. Параметр sender.email содержит email, который должен быть указан в качестве отправителя, а sender.text – произвольное текстовое имя для этого email.
Вам нужно прописать свой логин, свой почтовый ящик, связанный с этим логином, а также пароль от него. Но это не пароль от вашей учётки, а специальный сервисный пароль. Его можно получить в разделе «Пароли приложений» в настройках профиля Яндекс ID.
Почтовый ящик Google подключается похожим образом.
Теперь давайте создадим data class для запроса, в котором будем указывать email получателя. Назовём этот класс SingleReceiverRequest, который будет иметь лишь один параметр:
Далее создадим новый сервис EmailService и внедрим в него стандартный JavaMailSender, а также пару свойств из конфига.
Теперь добавим в наш сервис первый метод sendTextEmail(). Отправка простого текстового письма без форматирования выглядит так:
Тут мы создаём новый экземпляр сообщения SimpleMailMessage. Устанавливаем отправителя из конфига (метод setFrom()) и получателя письма (метод setTo()). Задаём тему письма через метод setSubject() и текст письма через setText(). Затем отправляем письмо. Как видите, ничего сложного. В результате получателю придёт обычное текстовое письмо.
Тестовый контроллер, который вызывает данный метод, выглядит следующим образом:
В него Spring автоматически внедрит созданный нами сервис. Для отправки тестового письма нам нужно выполнить POST-запрос по урлу 127.0.0.1:8080/emails/text, в теле которого надо указать почтовый ящик получателя:
Теперь давайте усложним задачу. Добавим в письмо форматирование, для отправителя будем указывать более читаемое имя, а также будем одновременно отправлять письма нескольким получателям.
Для этого создадим ещё один класс MultipleReceiverRequest со следующими полями:
В запросе мы будем указывать нескольких получателей списком в параметре receivers. Кроме того, в параметре copy мы можем указать получателя, который будет отображаться в поле «Копия» в интерфейсе почтового агента. Обычно в этом поле указывают людей, которых нужно поставить в известность, но письмо адресовано не им. Наконец, в поле hiddenCopy будем указывать скрытых получателей. Они также получат письмо, но ни в получателях, ни в «копии» они отображаться не будут.
Теперь добавим новый метод sendHtmlEmail() в сервисный слой:
Здесь мы создаём новое сообщение через createMimeMessage(). Затем для работы с ним используем обёртку MimeMessageHelper.
В качестве отправителя устанавливаем объект InternetAddress, который содержит не только email отправителя, но и его имя (произвольный текст для удобства).
Список получателей мы извлекаем из запроса и с помощью метода toTypedArray() преобразуем список в массив. Затем этих получателей мы устанавливаем через setTo(). Получателей для «копии» и «скрытой копии» устанавливаем через setCc() и setBcc() соответственно. В оба этих метода также можно передать список адресов с помощью массива.
Сам форматированный текст устанавливаем через метод setText() с флагом true, который указывает на то, что это html-формат.
Наконец, добавим новый метод sendHtmlEmail() в контроллер:
Теперь давайте запустим проект и отправим следующий запрос на урл 127.0.0.1:8080/emails/html:
В итоге на все 4 ящика придёт одинаковое письмо с html-форматированием. Ящики mail1 и mail2 будут стоять в графе получателей. mail3 будет указан в графе «Копия». Однако пользователи mail1, mail2, mail3 не увидят, что письмо также пришло на ящик mail4.
Итак, если вам нужно отправить простое текстовое уведомление на почтовый ящик, используйте класс SimpleMailMessage. Этот вариант больше подходит для каких-то технических уведомлений, т.к. совсем не содержит форматирования.
Если же вы отправляете письмо пользователю вашей системы, скорее всего вам подойдёт MimeMessageHelper(). Он позволяет сделать html-форматирование вашего уведомления. Здесь можно использовать заранее заготовленный html-шаблон, в котором нужные параметры можно подменять через String.replace().
Если вы хотите в графе отправителя или получателя отображать не только адрес, но и читаемое имя, используйте InternetAddress.
Получателей, которым адресовано письмо, надо указывать через метод setTo(). Если каким-то пользователям письмо не адресовано напрямую, но вы хотите поставить их в известность, используйте setCc(). Наконец, если нужно кому-то отправить копию письма, но чтобы об этом не узнали другие – используйте setBcc(). Каждый из этих трёх методов принимает как единственный адрес почтового ящика, так и список адресов в виде массива.
Kotlin, Java, Spring, Spring Boot, Spring Data, SQL, PostgreSQL, Oracle, Linux, Hibernate, Collections, Stream API, многопоточность, файлы, Nginx, Apache, maven, gradle, JUnit, YouTube, новости, руководство, ООП, алгоритмы, головоломки, rest, GraphQL, Excel, XML, json, yaml.