SpringBoot Thymeleaf メール送信 HTML TEXT 両対応 multipart

今回は、SpringBootでメール送信を実装するメモです。

Thymeleafとテキストファイルをテンプレートとしてメールの雛形にします。

※2024/12/28更新
サンプルコードのインデント誤り等を修正

また、メールにはHTML・TEXTと形式があると思いますが、

1通のメール送信で、両形式に対応したメール送信を行います。

SpringBoot mail MailHog

SpringBoot mail MailHog

 

SpringBootの基本的な内容は、以下の試したプロジェクトとほぼ同じ内容です。

試した際も追記する形で試してみました。

SpringBoot メール送信 実装 サンプル MailHog

環境

  • macOS:Big Sur 11.5.2
  • IntelliJ(Ultimate Edition):2023.1
  • MailHog:1.0.1

Gradle 設定ファイル

・build.gradle

plugins {
    id 'java'
    id 'org.springframework.boot' version '3.1.0'
    id 'io.spring.dependency-management' version '1.1.0'
}

group = 'com.example'
version = '0.0.1-SNAPSHOT'
sourceCompatibility = '17'

repositories {
    mavenCentral()
}

dependencies {
    implementation 'org.springframework.boot:spring-boot-starter-mail'
    implementation 'org.springframework.boot:spring-boot-starter-web'
    implementation 'org.springframework.boot:spring-boot-starter-thymeleaf'
}

tasks.named('test') {
    useJUnitPlatform()
}

尚、実際にメール実装で利用しているのは、

spring-boot-starter-mail、spring-boot-starter-thymeleafです。

spring-boot-starter-webは、挙動確認の簡易API実装用として利用しています。


メールサーバー設定

ローカル開発環境で、メール送信テストを行うために、MailHogを利用しました。

メールサーバーの設定は、MailHogのデフォルトのまま指定しています。

# local SMTP settings
spring.mail.host=localhost
spring.mail.port=1025
spring.mail.username=user
spring.mail.password=pass

SpringBoot mail properties

MailHogについては、以下を参考にして頂ければと思います。

MailHog 開発環境用 メールサーバー Docker


メール送信用テンプレート作成

今回は、HTML形式とTEXT形式の両方(計1通)でメール送信したいので、

HTMLメールとTEXTメールの両方の雛形を作成します。

・HTMLメール

src/main/resources/mail/html/htmlMail.html

<html>
<head>
    <meta http-equiv="Content-Type" content="text/html" charset="UTF-8"/>
</head>
<body>
・HTMLメール
<h1 th:text="${h1_text}"></h1>
<ul th:each="item : ${items}">
    <li th:utext="${item}"></li>
</ul>
<hr>
</body>
</html>

SpringBoot mail template

・テキストメール

src/main/resources/mail/text/textMail.txt

[#th:block th:utext="${h1_text}" /]
-----------------------------------------
[#th:block th:each="item : ${items}"]
[#th:block th:utext="${item}" /]
[/th:block]

SpringBoot mail template 


メール送信処理実装(コントローラクラス)

今回は、メール送信処理にJavaMailSenderを利用し、

メール内容を作成するのに、MimeMessageやMimeMessageHelperを利用します。

シンプルなメールだけを送信する場合、

MailSender(メール送信処理)とSimpleMailMessage(メール内容作成)だけでも事足りるのですが、

メールにファイルを添付したり、今回のようなケースの場合対応できないので利用します。

package com.example.springbootmailsample.controller;

import jakarta.mail.MessagingException;
import jakarta.mail.internet.MimeMessage;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.mail.javamail.JavaMailSender;
import org.springframework.mail.javamail.MimeMessageHelper;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
import org.thymeleaf.context.Context;
import org.thymeleaf.spring6.SpringTemplateEngine;
import org.thymeleaf.templateresolver.ClassLoaderTemplateResolver;

import java.nio.charset.StandardCharsets;
import java.util.Arrays;
import java.util.HashMap;
import java.util.Map;

@RestController
public class SendMailUsingTemplate {

    @Autowired
    JavaMailSender javaMailSender;

    @GetMapping("/sendTemplateMail")
    public String sendTemplateMail() {

        final SpringTemplateEngine engine = new SpringTemplateEngine();
        final ClassLoaderTemplateResolver templateResolver = new ClassLoaderTemplateResolver();
        templateResolver.setCharacterEncoding("UTF-8");
        engine.setTemplateResolver(templateResolver);

        final Map<String, Object> variables = new HashMap<>();
        variables.put("h1_text", "てすとテンプレートメール");
        variables.put("items", Arrays.asList("りんご", "ばなな"));

        final Context context = new Context();
        context.setVariables(variables);
        final String textBody = engine.process("/mail/text/textMail.txt", context);
        final String htmlBody = engine.process("/mail/html/htmlMail.html", context);

        try {
            final MimeMessage mimeMessage = this.javaMailSender.createMimeMessage();
            // MimeMessageHelper 第2引数でマルチパート指定
            final MimeMessageHelper helper = new MimeMessageHelper(mimeMessage, true, StandardCharsets.UTF_8.name());
            helper.setFrom("aaa@test.com");
            helper.setTo("bbb@test.com");
            helper.setSubject("テンプレートメール送信テスト");
            helper.setText(textBody, htmlBody);

            this.javaMailSender.send(mimeMessage);
        } catch (MessagingException e) {
            throw new RuntimeException(e);
        }
        return "send Template Mail. check MailHog.";
    }
}

SpringBoot mail JavaMailSender MimeMessage

ソースを上から確認していきますと、

まず、テンプレートエンジンを利用するために、SpringTemplateEngineとClassLoaderTemplateResolverを用意します。

final SpringTemplateEngine engine = new SpringTemplateEngine();
final ClassLoaderTemplateResolver templateResolver = new ClassLoaderTemplateResolver();
templateResolver.setCharacterEncoding("UTF-8");
engine.setTemplateResolver(templateResolver);

その後、テンプレートを指定しつつ、HTML・TEXTそれぞれメール本文利用するための準備を行います。

final Context context = new Context();
context.setVariables(variables);
final String textBody = engine.process("/mail/text/textMail.txt", context);
final String htmlBody = engine.process("/mail/html/htmlMail.html", context);
そして、メール内容を組み立てて、最後にメール送信しています。
今回は1通のメールでHTML・TEXTの両形式で送信するため、MimeMessageHelperをマルチパートで用意しています。
メール本文を設定するsetText部分でも、HTML・TEXTの両形式を指定しています。
// メール内容 送信前組み立て
final MimeMessage mimeMessage = this.javaMailSender.createMimeMessage();
// TEXT・HTMLの両形式で送信するため、MimeMessageHelper第2引数にて、マルチパート指定を行います。
final MimeMessageHelper helper = new MimeMessageHelper(mimeMessage, true, StandardCharsets.UTF_8.name());
helper.setFrom("aaa@test.com");
helper.setTo("bbb@test.com");
helper.setSubject("テンプレートメール送信テスト");
helper.setText(textBody, htmlBody);
// メール送信処理
this.javaMailSender.send(mimeMessage);

尚、HTMLメールのみ、TEXTメールのみの場合、

片方のメール内容だけ作成して、setTextを使い分けることで対応できます。

final String htmlBody = engine.process("/mail/html/htmlMail.html", context);

try {
    final MimeMessage mimeMessage = this.javaMailSender.createMimeMessage();
    final MimeMessageHelper helper = new MimeMessageHelper(mimeMessage, true, StandardCharsets.UTF_8.name());
    helper.setFrom("aaa@test.com");
    helper.setTo("bbb@test.com");
    helper.setSubject("テンプレートメール送信テスト");
    helper.setText(htmlBody, true); // 第1引数:メール内容、第2引数:html形式か否か

    this.javaMailSender.send(mimeMessage);
} catch (MessagingException e) {
    throw new RuntimeException(e);
}

挙動確認

MailHogが起動している状態で行います。

SpringBoot mail Mailhog

サンプル用に実装したAPIを実行します。

http://localhost:8080/sendTemplateMail

SpringBoot mail sample

 

API実行後、MailHogのメール一覧を確認します。

SpringBoot mail MailHog

メールの詳細を確認して、HTML形式とTEXT形式の両方でメールを確認できたら、

正常に送信されています。

SpringBoot mail MailHog

SpringBoot mail MailHog


今回のメモは以上となります。

普段見かけるメールは、HTMLメールが多いですが、

念のためPlain textメールを送信することが多いと思います。

また、メールにファイルを添付する場合なども、

MimeMessageHelperをマルチパートで利用すると対応できますので、

参考にして頂ければと思います。

都内でエンジニアをやっています。 2017年に脱サラ(法人設立)しました。 仕事で調べたことや、気になったことをメモしています。
投稿を作成しました 192

コメントを残す

メールアドレスが公開されることはありません。 ※ が付いている欄は必須項目です

CAPTCHA


関連投稿

検索語を上に入力し、 Enter キーを押して検索します。キャンセルするには ESC を押してください。

トップに戻る