はじめに
この記事では、Spring Boot における基本的なメール送信機能の実装方法と、MailHog を使ってローカル環境でメールの内容や挙動を確認する方法を説明します。
この記事でカバーする内容
- Spring Boot によるメール送信機能の実装方法
- MailHog を使ったローカル環境でのメールの確認方法
記事中のソースコードは以下のリポジトリから参照できます。
環境
- Spring Boot: 3.1.0
- Java: OpenJDK 17
- Gradle: 8.8
- Docker: 24.0.5
- Docker Desktop: 4.33.1
- Docker Compose: 2.20.2-desktop.1
- MailHog 1.0.1(Dockerコンテナとして実行)
- Windows 11 Pro
Docker を使用した MailHog のセットアップ
MailHog とは
MailHog は、開発者が安全にメール送信機能をテストできるローカル環境用の SMTP サーバーです。
実際の SMTP サーバーを使わずに送信されるメールの内容や挙動を確認できるため、メール送信機能を実装する際にテスト環境として非常に便利です。
セットアップ手順
公式サイトからバイナリをダウンロードすることも可能ですが、今回は手軽さを優先して Docker を使ったセットアップ手順を紹介します。
1. Docker コンテナの起動
MailHog は Docker イメージとして提供されているため、以下のコマンドを実行するだけで簡単に起動できます。
$ docker run -d -p 1025:1025 -p 8025:8025 mailhog/mailhog
各オプションの意味は以下の通りです。
-
-d
: コンテナをバックグラウンドで実行 -
-p 1025:1025
: MailHog の SMTP サーバーポート -
-p 8025:8025
: MailHog の Web UI ポート
2. Web インターフェースの確認
MailHog の起動確認も兼ねて、Web UI を見てみましょう。ブラウザで http://localhost:8025 にアクセスします。
問題がなければ、次のような画面が表示されるはずです。
送信されたメールはこの画面に一覧表示され、各メールの内容や詳細も確認することができます。
Spring Boot を使ったメール送信機能の実装
Spring Boot を用いたメール送信機能の実装に移る前に、その概要を簡単に説明します。
Spring Boot のメール送信機能について
Spring Framework では、メール送信を簡単に行うための便利なユーティリティが提供されています。このユーティリティのおかげで、メール送信機能の実装は非常に簡素化されています。
特に Spring Boot を使用することで、メール送信機能の実装はさらに容易になります。Spring Boot には spring-boot-starter-mail
という便利なスターターが提供されているため、これをプロジェクトに追加するだけで必要なライブラリの導入と基本的な設定が自動的に行われます。
そのため、開発者はスムーズにメール送信機能の実装を開始することができます。
実装方法
以下に、Spring Boot を使用したメール送信機能の具体的な実装方法を示します。
1. 依存関係の追加
まず、Spring Boot プロジェクトに spring-boot-starter-mail
依存関係を追加します。
build.gradle
の dependencies
に以下を追加してください。
dependencies {
// omitted
implementation 'org.springframework.boot:spring-boot-starter-mail'
implementation 'org.springframework.boot:spring-boot-starter-web'
}
ここでは、メール送信の確認用エンドポイントを作成するために spring-boot-starter-web
も追加しています。
2. 依存関係の反映
依存関係を追加したら、プロジェクトに反映させるために以下のコマンドを実行します。
$ ./gradlew build --refresh-dependencies
3. プロパティの設定
つぎに、SMTP サーバー (今回は MailHog) の情報をプロパティとして設定します。
この値を設定することで、Spring Boot アプリケーションは MailHog を使用してメールを送信できるようになります。
application.properties
に以下を追加してください。
spring.mail.host=localhost
spring.mail.port=1025
ここで指定するホスト名とポート番号は、コンテナ起動時に指定した MailHog の設定値に合わせます。
4. JavaMailSender を使用したメール送信処理の実装
Spring Framework でアプリケーションにメール送信機能を組み込む際は、要件に応じて以下の 2 つの主要な方法を選択できます。
1. MailSender: プレーンテキストメール送信
-
MailSender
は、org.springframework.mail
パッケージに含まれる基本的なインターフェースで、主にシンプルなプレーンテキストメールの送信に使用されます。 -
SimpleMailMessage
クラスを利用して、件名、本文、送信先などを簡単に設定できるため、英語の通知メールやアラートメールなど、簡易的な用途に適しています。
2. JavaMailSender: HTML メールや添付ファイルの送信など
-
JavaMailSender
は、MailSender
を拡張したインターフェースで、より複雑なメールの送信をサポートします。HTML メールや添付ファイルを含むメール、または日本語などのマルチバイト文字を扱う際に推奨されます。 -
MimeMessage
クラスを用いて、メールの内容を柔軟に構築することが可能です。 - 特に、
MimeMessageHelper
を使用すると、メールのフォーマットやエンコーディングが簡単に設定でき、直感的に HTML メールを作成できます。
今回はより柔軟性が高く、HTML メールやマルチバイト文字を含むメールを簡単に扱える JavaMailSender
を使用した実装方法を説明します。
@Component
public class EmailSenderClient {
private final JavaMailSender javaMailSender; // 1. JavaMailSender の準備
@Autowired
public EmailSenderClient(JavaMailSender javaMailSender) {
this.javaMailSender = javaMailSender;
}
public void sendMail(String emailAddress) {
MimeMessage mimeMessage = javaMailSender.createMimeMessage(); // 2. MimeMessage の作成
try {
// 3. MimeMessageHelper を使用して MIME メッセージを構成
MimeMessageHelper helper = new MimeMessageHelper(mimeMessage, true, "UTF-8");
helper.setFrom("me@mail.com");
helper.setTo(emailAddress);
helper.setSubject("件名");
helper.setText("<html><body><h3>テストメール</h3>本文</body></html>", true); // 第二引数に true を指定することで、Content-Type が text/html になる
javaMailSender.send(mimeMessage); // 4. メールの送信
} catch (MessagingException | MailException ex) {
System.err.println(ex.getMessage());
}
}
}
1. JavaMailSender の準備
JavaMailSender
インターフェースをインジェクトします。
メール送信の基盤となる org.springframework.mail
パッケージには、基本的なメール送信操作を定義する MailSender
インターフェースが含まれています。このインターフェースを利用することで、メール送信に関する多くの手間を省くことができます。
とくに Spring Boot では、spring-boot-starter-mail
をプロジェクトに追加することで JavaMailSender
が自動的に構成されるため、設定は必要ありません。
2. MimeMessage の作成
JavaMailSender
の createMimeMessage
メソッドを使用して MimeMessage
オブジェクトを作成します。
MimeMessage
は Jakarta Mail の標準クラスで、マルチバイト文字、HTML、添付ファイルを含む複雑なメール構造を直感的に扱うことができます。
3. MimeMessageHelper を使用してメッセージを構成
MimeMessageHelper
クラスを使用して、MimeMessage
の設定を行います。
MimeMessageHelper
は、JavaMail API の冗長さを解消し、MimeMessage
オブジェクトの作成を簡素化するために設計されたクラスです。
コンストラクタには true
を指定することで、multipart メッセージを使用することを示しています。また、日本語を適切に扱うために、文字エンコーディングとして UTF-8 を指定します。
4. メールの送信
構築した MimeMessage
を JavaMailSender
の send
メソッドで送信します。
このメソッドは、プロパティファイルで設定した SMTP サーバーを介して受信者にメールを届ける役割を果たします。
5. 使用例
EmailSenderClient
クラスを使用して実際にメールを送信する例を示します。
@RestController
@RequestMapping("/mail/send")
public class MailController {
private final EmailSenderClient emailSenderClient;
public MailController(EmailSenderClient emailSenderClient) {
this.emailSenderClient = emailSenderClient;
}
@PostMapping
public void sendMail(@RequestParam String from) {
emailSenderClient.sendMail(from);
}
}
このコントローラクラスは、/mail/send
エンドポイントを介してメールを送信するためのエントリーポイントとして機能します。POST リクエストを受け取ると、EmailSenderClient
を利用して指定されたメールアドレスにメールが送信されます。
6. 動作確認
最後にアプリケーションを起動させて、正しく動作するか確認しましょう。
以下のコマンドを実行するなどして、アプリケーションを起動させてください。
$ ./gradlew bootRun
アプリケーションが起動したら、ブラウザや Postman などのツールを使用して、以下のようにリクエストを送信します。
POST http://localhost:8080/mail/send?from=you@mail.com
このリクエストを送信すると、指定されたメールアドレスに対してメールが送信されます。
ブラウザで http://localhost:8025 にアクセスして MailHog の Web UI を開くと、次のように送信されたメールが一覧に追加されているはずです。
メールを選択すると、メールの内容や詳細を確認できます。
送信元 (From) にはリクエストに指定したメールアドレスが使用され、HTML フォーマットのメール本文も問題なく表示されていますね。
さいごに
今回は Spring Boot と MailHog を使用して、ローカル環境でメールを送信する方法について説明しました。
実際の開発では、この基本的な実装に加えて、セキュリティ面でのメールヘッダ・インジェクション攻撃への対策、パフォーマンスを考慮した適切なタイムアウト値の設定、そしてシステムの信頼性を高めるための適切な例外処理の実装などに注意を払う必要があります。
これらの要素を十分に考慮しながら、Spring Boot の提供する利点を最大限に活用することで、効率的かつ堅牢なメール送信機能を実装することができるかと思います。
Spring Boot の強力な機能と MailHog の便利さにより、非常に簡単にメール送信機能が実装できることがお伝えできれば幸いです。
それでは、最後までお読みいただき、ありがとうございました。
参考
▼ E-mail送信(SMTP) — Macchinetta Server Framework Development Guideline
▼ Sending Email :: Spring Boot
▼ Email :: Spring Framework
▼ Guide to Spring Email | Baeldung