2
4

More than 1 year has passed since last update.

[Spring]メール送信機能

Posted at

はじめに

spring-boot-starter-mailを使用して、Gmailでメールを送信できるようにしていきます
基本的に詳細はjavadocで記載しています

環境

Java 11
Spring Boot 2.6.1
Gradle 2.24
spring-boot-starter-mail 2.6.1

依存の追加

build.gradle
dependencies {
    implementation group: 'org.springframework.boot', name: 'spring-boot-starter-mail', version: '2.6.1'
}

設定の追加

今回はGmailを使用します

application.properties
spring.mail.default-encoding=UTF-8
spring.mail.protocol=smtp
spring.mail.host=smtp.gmail.com
spring.mail.port=587
spring.mail.username=hogehoge@gmail.com
spring.mail.password=hogehoge
spring.mail.properties.mail.smtp.auth=true
spring.mail.properties.mail.smtp.starttls.enable=true
sender.mail-address=hogehoge@gmail.com

HTMLテンプレートConfiguration

DIコンテナへ登録するHTMLテンプレートConfigurationを作成していきます

HtmlTemplateConfig.java
@Configuration
public class HtmlTemplateConfig {

    @Bean
    @Primary
    public ClassLoaderTemplateResolver templateResolver() {
        ClassLoaderTemplateResolver templateResolver = new ClassLoaderTemplateResolver();
        templateResolver.setPrefix("templates/");
        templateResolver.setCacheable(false);
        templateResolver.setSuffix(".html");
        templateResolver.setTemplateMode("HTML5");
        templateResolver.setCharacterEncoding("UTF-8");
        return templateResolver;
    }

    @Bean
    @Primary
    public SpringTemplateEngine templateEngine() {
        SpringTemplateEngine templateEngine = new SpringTemplateEngine();
        templateEngine.addTemplateResolver(templateResolver());
        templateEngine.addDialect(new Java8TimeDialect());
        return templateEngine;
    }

    @Bean
    @Primary
    public ThymeleafViewResolver viewResolver() {
        ThymeleafViewResolver viewResolver = new ThymeleafViewResolver();
        viewResolver.setTemplateEngine(templateEngine());
        viewResolver.setCharacterEncoding("UTF-8");
        return viewResolver;
    }

}

メールテンプレートConfiguration

続いて、メールのテンプレートエンジンを使用するための、メールテンプレートに関するConfigurationを作成していきます

MailTemplateConfig.java
@Configuration
public class MailTemplateConfig {

    private final TemplateMode templateMode = TemplateMode.TEXT;
    private final Charset charset = StandardCharsets.UTF_8;

    /**
     * メールのテンプレートエンジンを使用するための設定インスタンスを生成します。
     * @return {@link ClassLoaderTemplateResolver}
     */
    @Bean(name = "mailTemplateResolver")
    public ClassLoaderTemplateResolver mailTemplateResolver() {
        val templateResolver = new ClassLoaderTemplateResolver();
        templateResolver.setTemplateMode(templateMode);
        templateResolver.setCharacterEncoding(charset.name());
        return templateResolver;
    }

    /**
     * メールのテンプレートエンジンを使用するためのインスタンスを生成します。
     * @return {@link SpringTemplateEngine}
     */
    @Bean(name = "mailTemplateEngine")
    public SpringTemplateEngine mailTemplateEngine(@Qualifier("mailTemplateResolver") ClassLoaderTemplateResolver classLoaderTemplateResolver) {
        val templateEngine = new SpringTemplateEngine();
        templateEngine.setTemplateResolver(classLoaderTemplateResolver);
        return templateEngine;
    }

}

テンプレートファイル

メール本文のテンプレートファイルを作成します

sample.txt
タイトル
[(${title})]

内容
[(${body})]

メールテンプレートのインターフェース

テンプレートに埋め込む準備をしていきます

MailTemplate.java
public interface MailTemplate {
    /**
     * テンプレートファイルのパスを取得します。
     * @return テンプレートファイルパス
     */
    String getTemplatePath();

    /**
     * テンプレートに埋め込む変数と値のマップを取得します。
     * @return テンプレートに埋め込む変数と値のマップ
     */
    Map<String, Object> getVariables();
}

メールテンプレートの実装

先程作成したテンプレートのインターフェースを実装していきます

SampleMailTemplate.java
@RequiredArgsConstructor
public class SampleMailTemplate implements MailTemplate {
    // テンプレートパス
    private static final String TEMPLATE_PATH = "/mail/sample.txt";

    // テンプレート変数
    /** タイトル */
    private final String title;
    /** 内容 */
    private final String body;

    /**
     * {@inheritDoc}
     */
    @Override
    public String getTemplatePath() {
        return TEMPLATE_PATH;
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public Map<String, Object> getVariables() {
        val variables = new HashMap<String, Object>();
        variables.put("title", title);
        variables.put("body", body);
        return variables;
    }
}

メール本文Factory

メール本文を作成するFactoryを作成していきます

MailContentFactory.java
@Component
public class MailContentFactory {
    private final SpringTemplateEngine templateEngine;

    /**
     * メール本文を作成します。
     */
    public String create(MailTemplate mailTemplate) {
        return getContent(mailTemplate);
    }

    /**
     * メールのメッセージを取得します。
     * @param mailTemplate メールテンプレート
     * @return メールのメッセージ
     */
    private String getContent(MailTemplate mailTemplate) {
        return templateEngine.process(mailTemplate.getTemplatePath(), getVariables(mailTemplate));
    }

    /**
     * テンプレートのパラメータ情報を取得します。
     * @param mailTemplate メールテンプレート
     * @return {@link Context}
     */
    private Context getVariables(MailTemplate mailTemplate) {
        val context = new Context();
        context.setVariables(mailTemplate.getVariables());
        return context;
    }

    /**
     * コンストラクタ
     * @param templateEngine メールテンプレートエンジン
     */
    private MailContentFactory(@Qualifier("mailTemplateEngine") SpringTemplateEngine templateEngine) {
        this.templateEngine = templateEngine;
    }
}

メールBuilder

MailMessageBuilder.java
public class MailMessageBuilder {
    private final SimpleMailMessage mailMessage = new SimpleMailMessage();

    /**
     * 差出人を設定します。
     * @param from 差出人
     * @return {@link MailMessageBuilder}
     */
    public MailMessageBuilder from(String from) {
        this.mailMessage.setFrom(from);
        return this;
    }

    /**
     * 宛先を設定します。
     * @param to 宛先
     * @return {@link MailMessageBuilder}
     */
    public MailMessageBuilder to(String to) {
        this.mailMessage.setTo(to);
        return this;
    }

    /**
     * 宛先を設定します。
     * @param to 宛先
     * @return {@link MailMessageBuilder}
     */
    public MailMessageBuilder to(List<String> to) {
        this.mailMessage.setTo(to.toArray(new String[0]));
        return this;
    }

    /**
     * Bccを設定します。
     * @param bcc Bcc
     * @return {@link MailMessageBuilder}
     */
    public MailMessageBuilder bcc(String bcc) {
        this.mailMessage.setBcc(bcc);
        return this;
    }

    /**
     * 件名を設定します。
     * @param subject 件名
     * @return {@link MailMessageBuilder}
     */
    public MailMessageBuilder subject(String subject) {
        this.mailMessage.setSubject(subject);
        return this;
    }

    /**
     * 本文を設定します。
     * @param content 本文
     * @return {@link MailMessageBuilder}
     */
    public MailMessageBuilder content(String content) {
        this.mailMessage.setText(content);
        return this;
    }

    /**
     * ビルドしたメールを取得します。
     * @return {@link SimpleMailMessage}
     */
    public SimpleMailMessage build() {
        return mailMessage;
    }

}

メール送信サービス

MailSendRepository.java
@Repository
@RequiredArgsConstructor
public class MailSendRepository {

    @Value("${sender.mail-address}")
    private String fromEmail;

    private final MyMailSender mailSender;
    private final MailContentFactory mailContentFactory;

    /**
     * サンプルメールを送信します。
     * @param title タイトル
     * @param body 内容
     * @param toEmailAddress 送り先アドレス
     */
    @Async
    public void sendSampleMail(String title, String body, String toEmailAddress) {

        // メール内容作成
        String content = mailContentFactory.create(
                new SampleMailTemplate(
                        title,
                        body));

        // メール設定
        val mailMessage = new MailMessageBuilder()
                .from(fromEmail)
                .to(toEmailAddress)
                .subject("サンプルメールです。")
                .content(content)
                .build();

        // メール送信
        mailSender.send(mailMessage);
    }
}

最後に

ご覧いただきありがとうございます。
間違っている、気になる等ありましたら、優しく諭していただけるととても喜びます。

2
4
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
4