Статьи
Утилиты Telegram YouTube Отзывы

Как отправлять email в Spring Boot (kotlin)

Видеогайд Исходники

25 февраля 2023

Тэги: gradle, Java, Kotlin, Spring, Spring Boot, YouTube.

Содержание

  1. Настройки подключения
  2. Письмо без форматирования
  3. Письмо с форматированием и несколькими получателями
  4. Выводы

В этой статье вы узнаете, как отправлять email в Spring Boot. Также можно посмотреть исходники этого примера на github и видео на YouTube.

Для начала создадим новый gradle-проект. Проще всего это сделать с помощью Spring Initializr. Там выбираем параметры Java 17, язык – Kotlin, сборщик Gradle – Kotlin. В зависимости добавим Spring Web и Java Mail Sender. В итоге в проекте должно быть прописано:

implementation("org.springframework.boot:spring-boot-starter-web")
implementation("org.springframework.boot:spring-boot-starter-mail")

Стартер spring-boot-starter-mail добавляет саму функциональность работы с email.

Настройки подключения

Теперь в папке resources переименуем файл application.properties в application.yml и добавим в него параметры подключения к почтовому ящику, через который будем отправлять письма:

spring:
  mail:
    host: smtp.yandex.ru
    port: 465
    username: your_name # логин от учётки Yandex
    password: your_password # специальный пароль для приложения
    test-connection: true # проверка подключения при старте приложения
    properties:
      mail:
        smtp:
          auth: true
          ssl:
            enable: true
    sender: # отправитель письма (его почта и имя)
      email: your_name@yandex.ru
      text: no-reply

Здесь я использую почтовый ящик Yandex. Мы указываем хост и порт mail-сервера, а также логин/пароль для доступа к нему. Параметр test-connection отвечает за проверку подключения к серверу при старте приложения. Параметр sender.email содержит email, который должен быть указан в качестве отправителя, а sender.text – произвольное текстовое имя для этого email.

Вам нужно прописать свой логин, свой почтовый ящик, связанный с этим логином, а также пароль от него. Но это не пароль от вашей учётки, а специальный сервисный пароль. Его можно получить в разделе «Пароли приложений» в настройках профиля Яндекс ID.

Почтовый ящик Google подключается похожим образом.

Письмо без форматирования

Теперь давайте создадим data class для запроса, в котором будем указывать email получателя. Назовём этот класс SingleReceiverRequest, который будет иметь лишь один параметр:

data class SingleReceiverRequest(
    val receiver: String,
)

Далее создадим новый сервис EmailService и внедрим в него стандартный JavaMailSender, а также пару свойств из конфига.

@Service
class EmailService(
    private val javaMailSender: JavaMailSender,
    @Value("\${spring.mail.sender.email}") private val senderEmail: String,
    @Value("\${spring.mail.sender.text}") private val senderText: String
) {

Теперь добавим в наш сервис первый метод sendTextEmail(). Отправка простого текстового письма без форматирования выглядит так:

fun sendTextEmail(request: SingleReceiverRequest) {
    val message = SimpleMailMessage()
    message.setFrom(senderEmail)
    message.setTo(request.receiver)
    message.setSubject("Тестовое письмо")
    message.setText("Текстовое сообщение в тестовом письме.\nВторая строка.")
    javaMailSender.send(message)
}

Тут мы создаём новый экземпляр сообщения SimpleMailMessage. Устанавливаем отправителя из конфига (метод setFrom()) и получателя письма (метод setTo()). Задаём тему письма через метод setSubject() и текст письма через setText(). Затем отправляем письмо. Как видите, ничего сложного. В результате получателю придёт обычное текстовое письмо.

Тестовый контроллер, который вызывает данный метод, выглядит следующим образом:

@RestController
@RequestMapping("/emails")
class EmailController(private val emailService: EmailService) {

    @PostMapping("/text")
    fun sendTextEmail(@RequestBody request: SingleReceiverRequest) {
        emailService.sendTextEmail(request)
    }
}

В него Spring автоматически внедрит созданный нами сервис. Для отправки тестового письма нам нужно выполнить POST-запрос по урлу 127.0.0.1:8080/emails/text, в теле которого надо указать почтовый ящик получателя:

{
    "receiver": "example@example.com"
}

Письмо с форматированием и несколькими получателями

Теперь давайте усложним задачу. Добавим в письмо форматирование, для отправителя будем указывать более читаемое имя, а также будем одновременно отправлять письма нескольким получателям.

Для этого создадим ещё один класс MultipleReceiverRequest со следующими полями:

data class MultipleReceiverRequest(
    val receivers: List<String>,
    val copy: String,
    val hiddenCopy: String,
)

В запросе мы будем указывать нескольких получателей списком в параметре receivers. Кроме того, в параметре copy мы можем указать получателя, который будет отображаться в поле «Копия» в интерфейсе почтового агента. Обычно в этом поле указывают людей, которых нужно поставить в известность, но письмо адресовано не им. Наконец, в поле hiddenCopy будем указывать скрытых получателей. Они также получат письмо, но ни в получателях, ни в «копии» они отображаться не будут.

Теперь добавим новый метод sendHtmlEmail() в сервисный слой:

fun sendHtmlEmail(request: MultipleReceiverRequest) {
    val message = javaMailSender.createMimeMessage()
    val helper = MimeMessageHelper(message)
    helper.setFrom(InternetAddress(senderEmail, senderText))
    helper.setTo(request.receivers.toTypedArray())
    helper.setCc(request.copy)
    helper.setBcc(request.hiddenCopy)
    helper.setSubject("Тестовое письмо")
    helper.setText("<p>Сообщение в формате <b>Html</b>.<br>Вторая строка.</p>", true)
    javaMailSender.send(message)
}

Здесь мы создаём новое сообщение через createMimeMessage(). Затем для работы с ним используем обёртку MimeMessageHelper.

В качестве отправителя устанавливаем объект InternetAddress, который содержит не только email отправителя, но и его имя (произвольный текст для удобства).

Список получателей мы извлекаем из запроса и с помощью метода toTypedArray() преобразуем список в массив. Затем этих получателей мы устанавливаем через setTo(). Получателей для «копии» и «скрытой копии» устанавливаем через setCc() и setBcc() соответственно. В оба этих метода также можно передать список адресов с помощью массива.

Сам форматированный текст устанавливаем через метод setText() с флагом true, который указывает на то, что это html-формат.

Письмо с форматированием

Наконец, добавим новый метод sendHtmlEmail() в контроллер:

@PostMapping("/html")
fun sendHtmlEmail(@RequestBody request: MultipleReceiverRequest) {
    emailService.sendHtmlEmail(request)
}

Теперь давайте запустим проект и отправим следующий запрос на урл 127.0.0.1:8080/emails/html:

{
    "receivers": ["mail1@example.com", "mail2@example.com"],
    "copy": "mail3@example.com",
    "hiddenCopy": "mail4@example.com"
}

В итоге на все 4 ящика придёт одинаковое письмо с html-форматированием. Ящики mail1 и mail2 будут стоять в графе получателей. mail3 будет указан в графе «Копия». Однако пользователи mail1, mail2, mail3 не увидят, что письмо также пришло на ящик mail4.

Выводы

Итак, если вам нужно отправить простое текстовое уведомление на почтовый ящик, используйте класс SimpleMailMessage. Этот вариант больше подходит для каких-то технических уведомлений, т.к. совсем не содержит форматирования.

Если же вы отправляете письмо пользователю вашей системы, скорее всего вам подойдёт MimeMessageHelper(). Он позволяет сделать html-форматирование вашего уведомления. Здесь можно использовать заранее заготовленный html-шаблон, в котором нужные параметры можно подменять через String.replace().

Если вы хотите в графе отправителя или получателя отображать не только адрес, но и читаемое имя, используйте InternetAddress.

Получателей, которым адресовано письмо, надо указывать через метод setTo(). Если каким-то пользователям письмо не адресовано напрямую, но вы хотите поставить их в известность, используйте setCc(). Наконец, если нужно кому-то отправить копию письма, но чтобы об этом не узнали другие – используйте setBcc(). Каждый из этих трёх методов принимает как единственный адрес почтового ящика, так и список адресов в виде массива.



Комментарии

Добавить комментарий

×

devmark.ru