Перейти к основному содержимому

Руководство по электронной почте Spring

· 6 мин. чтения

1. Обзор

В этом руководстве мы рассмотрим шаги, необходимые для отправки электронных писем как из простого ванильного приложения Spring, так и из приложения Spring Boot. В первом случае мы будем использовать библиотеку JavaMail , а во втором — зависимость spring-boot-starter-mail .

2. Зависимости Maven

Во-первых, нам нужно добавить зависимости в наш pom.xml .

2.1. Весна

Вот что мы добавим для использования в простом ванильном фреймворке Spring:

<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context-support</artifactId>
<version>5.2.8.RELEASE</version>
</dependency>

Последнюю версию можно найти здесь .

2.2. Весенний ботинок

И для весенней загрузки:

<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-mail</artifactId>
<version>2.5.6</version>
</dependency>

Последняя версия доступна в репозитории Maven Central .

3. Свойства почтового сервера

Интерфейсы и классы для поддержки почты Java в среде Spring организованы следующим образом:

  1. Интерфейс MailSender : интерфейс верхнего уровня, предоставляющий базовые функции для отправки простых электронных писем.
  2. `Интерфейс JavaMailSender` : субинтерфейс вышеупомянутого MailSender . Он поддерживает сообщения MIME и в основном используется вместе с классом MimeMessageHelper для создания MimeMessage . С этим интерфейсом рекомендуется использовать механизм MimeMessagePreparator .
  3. `Класс JavaMailSenderImpl` предоставляет реализацию интерфейса JavaMailSender . Он поддерживает MimeMessage и SimpleMailMessage .
  4. `Класс SimpleMailMessage` : используется для создания простого почтового сообщения, включая поля «от», «кому», «копия», «тема» и «текст».
  5. Интерфейс MimeMessagePreparator предоставляет интерфейс обратного вызова для подготовки сообщений MIME.
  6. `Класс MimeMessageHelper` : вспомогательный класс для создания сообщений MIME. Он предлагает поддержку изображений, типичных почтовых вложений и текстового содержимого в макете HTML.

В следующих разделах мы покажем, как использовать эти интерфейсы и классы.

3.1. Свойства почтового сервера Spring

Свойства почты, необходимые для указания, например, SMTP-сервера, могут быть определены с помощью JavaMailSenderImpl .

Для Gmail это можно настроить, как показано ниже:

@Bean
public JavaMailSender getJavaMailSender() {
JavaMailSenderImpl mailSender = new JavaMailSenderImpl();
mailSender.setHost("smtp.gmail.com");
mailSender.setPort(587);

mailSender.setUsername("my.gmail@gmail.com");
mailSender.setPassword("password");

Properties props = mailSender.getJavaMailProperties();
props.put("mail.transport.protocol", "smtp");
props.put("mail.smtp.auth", "true");
props.put("mail.smtp.starttls.enable", "true");
props.put("mail.debug", "true");

return mailSender;
}

3.2. Свойства почтового сервера Spring Boot

После создания зависимости следующим шагом будет указание свойств почтового сервера в файле application.properties с использованием пространства имен spring.mail.* .

Мы можем указать свойства для SMTP-сервера Gmail следующим образом:

spring.mail.host=smtp.gmail.com
spring.mail.port=587
spring.mail.username=<login user to smtp server>
spring.mail.password=<login password to smtp server>
spring.mail.properties.mail.smtp.auth=true
spring.mail.properties.mail.smtp.starttls.enable=true

Некоторым SMTP-серверам требуется TLS-соединение, поэтому мы используем свойство spring.mail.properties.mail.smtp.starttls.enable , чтобы включить TLS-защищенное соединение.

3.2.1. Свойства SMTP Gmail

Мы можем отправить электронное письмо через SMTP-сервер Gmail. Просмотрите документацию , чтобы увидеть свойства SMTP-сервера исходящей почты Gmail.

Наш файл application.properties уже настроен на использование SMTP Gmail (см. предыдущий раздел).

Обратите внимание, что пароль для нашей учетной записи должен быть не обычным паролем, а паролем приложения, сгенерированным для нашей учетной записи Google. Перейдите по этой ссылке , чтобы просмотреть подробности и сгенерировать пароль для приложения Google.

3.2.2. Свойства SES SMTP

Чтобы отправлять электронные письма с помощью Amazon SES, мы устанавливаем наш application.properties :

spring.mail.host=email-smtp.us-west-2.amazonaws.com
spring.mail.username=username
spring.mail.password=password
spring.mail.properties.mail.transport.protocol=smtp
spring.mail.properties.mail.smtp.port=25
spring.mail.properties.mail.smtp.auth=true
spring.mail.properties.mail.smtp.starttls.enable=true
spring.mail.properties.mail.smtp.starttls.required=true

Имейте в виду, что Amazon требует от нас проверки наших учетных данных перед их использованием. Перейдите по ссылке , чтобы подтвердить свое имя пользователя и пароль.

4. Отправка электронной почты

После того, как управление зависимостями и настройка настроены, мы можем использовать вышеупомянутый JavaMailSender для отправки электронной почты.

Поскольку как обычная ванильная среда Spring, так и ее загрузочная версия одинаково обрабатывают создание и отправку электронных писем, нам не придется различать их в подразделах ниже.

4.1. Отправка простых писем

Давайте сначала составим и отправим простое сообщение электронной почты без каких-либо вложений:

@Component
public class EmailServiceImpl implements EmailService {

@Autowired
private JavaMailSender emailSender;

public void sendSimpleMessage(
String to, String subject, String text) {
...
SimpleMailMessage message = new SimpleMailMessage();
message.setFrom("noreply@foreach.com");
message.setTo(to);
message.setSubject(subject);
message.setText(text);
emailSender.send(message);
...
}
}

Обратите внимание, что хотя указывать адрес отправителя не обязательно , многие SMTP-серверы будут отклонять такие сообщения. Вот почему мы используем адрес электронной почты noreply@foreach.com в нашей реализации EmailService . ``

4.2. Отправка писем с вложениями

Иногда простого обмена сообщениями Spring недостаточно для наших случаев использования.

Например, мы хотим отправить электронное письмо с подтверждением заказа с прикрепленным счетом-фактурой. В этом случае мы должны использовать составное сообщение MIME из библиотеки JavaMail вместо SimpleMailMessage . Spring поддерживает обмен сообщениями JavaMail с классом org.springframework.mail.javamail.MimeMessageHelper .

Прежде всего, мы добавим в EmailServiceImpl метод для отправки электронных писем с вложениями:

@Override
public void sendMessageWithAttachment(
String to, String subject, String text, String pathToAttachment) {
// ...

MimeMessage message = emailSender.createMimeMessage();

MimeMessageHelper helper = new MimeMessageHelper(message, true);

helper.setFrom("noreply@foreach.com");
helper.setTo(to);
helper.setSubject(subject);
helper.setText(text);

FileSystemResource file
= new FileSystemResource(new File(pathToAttachment));
helper.addAttachment("Invoice", file);

emailSender.send(message);
// ...
}

4.3. Простой шаблон электронной почты

Класс SimpleMailMessage поддерживает форматирование текста.

Мы можем создать шаблон для электронных писем, определив bean-компонент шаблона в нашей конфигурации:

@Bean
public SimpleMailMessage templateSimpleMessage() {
SimpleMailMessage message = new SimpleMailMessage();
message.setText(
"This is the test email template for your email:\n%s\n");
return message;
}

Теперь мы можем использовать этот bean-компонент в качестве шаблона для электронной почты, и нам нужно только указать необходимые параметры для шаблона:

@Autowired
public SimpleMailMessage template;
...
String text = String.format(template.getText(), templateArgs);
sendSimpleMessage(to, subject, text);

5. Обработка ошибок отправки

JavaMail предоставляет SendFailedException для обработки ситуаций, когда сообщение не может быть отправлено. Но возможно, что мы не получим это исключение при отправке письма на неправильный адрес. Причина в следующем:

Спецификации протокола для SMTP в RFC 821 определяют код возврата 550, который SMTP-сервер должен возвращать при попытке отправить электронное письмо на неправильный адрес. Но большинство общедоступных SMTP-серверов этого не делают. Вместо этого они отправляют электронное письмо «ошибка доставки» или вообще не дают отзывов.

Например, SMTP-сервер Gmail отправляет сообщение «ошибка доставки». И у нас нет исключений в нашей программе.

Итак, у нас есть несколько вариантов решения этой проблемы:

  1. Перехватите SendFailedException , которое никогда не может быть выброшено.
  2. Проверьте наш почтовый ящик отправителя на наличие сообщения «доставка не удалась» в течение некоторого периода времени. Это не просто, и период времени не определен.
  3. Если наш почтовый сервер не дает никакой обратной связи, мы ничего не можем сделать.

6. Заключение

В этой быстрой статье мы показали, как настраивать и отправлять электронные письма из приложения Spring Boot.

Реализацию всех этих примеров и фрагментов кода можно найти на GitHub .