概要
通知メール、パスワードリセット、帳票の送付――業務システムでメール送信が必要になる場面は今でも多く残っています。Java 標準 API にはメール送信機能が含まれていませんが、Jakarta Mail(旧 JavaMail)を使えば、SMTP の接続設定からテキスト・HTML メールの組み立てまでを比較的少ないコードで実装できます。ただし、SMTP 認証の設定、STARTTLS と SSL/TLS の違い、日本語件名の文字コード指定、HTML メールでの MimeBodyPart の組み立てなど、初見で引っかかるポイントは少なくありません。この記事では、SMTP 設定の構造化から、テキストメール・HTML メールの送信、Java バージョンごとの書き方の違いまでを一通り整理します。開発環境では Mailtrap や MailHog を使うことで、実際のメールボックスに影響を与えずにテストできます。
使いどころ
ユーザー登録完了時に確認メールを自動送信し、認証リンクを本文に含める
月次バッチ処理の結果サマリーを管理者宛にテキストメールで送信する
請求書 PDF を HTML メールに添付して取引先へ送付する
コード例
import java.util.Properties;
/**
* Jakarta Mail によるメール送信のサンプル。
* 実行には pom.xml に jakarta.mail 依存の追加が必要です。
*
* <dependency>
* <groupId>com.sun.mail</groupId>
* <artifactId>jakarta.mail</artifactId>
* <version>2.0.1</version>
* </dependency>
*/
public class MailSender {
// SMTP 設定を record で構造化(Java 16+)
record SmtpConfig(String host, int port,
String username, String password,
boolean useTls) {}
/** SMTP 接続用の Properties を生成する */
static Properties buildSmtpProperties(SmtpConfig config) {
var props = new Properties();
props.put("mail.smtp.auth", "true");
props.put("mail.smtp.starttls.enable",
String.valueOf(config.useTls()));
props.put("mail.smtp.host", config.host());
props.put("mail.smtp.port",
String.valueOf(config.port()));
return props;
}
/*
* テキストメール送信(Jakarta Mail 使用時のコード構成)
*
* var session = Session.getInstance(props, authenticator);
* var message = new MimeMessage(session);
* message.setFrom(new InternetAddress(from));
* message.setRecipients(
* Message.RecipientType.TO, InternetAddress.parse(to));
* message.setSubject(subject, "UTF-8");
* message.setText(body, "UTF-8");
* Transport.send(message);
*/
static void sendTextMail(SmtpConfig config,
String from, String to,
String subject, String body) {
System.out.println("=== テキストメール送信 ===");
System.out.println("SMTP: " + config.host()
+ ":" + config.port());
System.out.println("From: " + from);
System.out.println("To: " + to);
System.out.println("件名: " + subject);
System.out.println("本文: " + body);
}
/*
* HTML メール送信(テキストブロックで HTML を記述)
*/
static void sendHtmlMail(SmtpConfig config,
String from, String to, String subject) {
var htmlBody = """
<!DOCTYPE html>
<html>
<body>
<h1 style="color: #2563eb;">お知らせ</h1>
<p>Jakarta Mail を使った
<strong>HTML メール</strong>のサンプルです。</p>
</body>
</html>
""";
System.out.println("=== HTML メール送信 ===");
System.out.println("SMTP: " + config.host()
+ ":" + config.port());
System.out.println("To: " + to);
System.out.println("件名: " + subject);
}
public static void main(String[] args) {
var config = new SmtpConfig(
"smtp.gmail.com", 587,
"[email protected]", "your-app-password",
true
);
sendTextMail(config,
"[email protected]", "[email protected]",
"テスト件名", "テスト本文です。");
System.out.println();
sendHtmlMail(config,
"[email protected]", "[email protected]",
"HTML メールテスト");
}
}Version Coverage
jakarta.mail パッケージに移行。var による型推論で記述量が減る。テキストブロックで HTML メール本文を読みやすく記述できる。SMTP 設定を record で構造化するのも効果的。
// Java 17: record で SMTP 設定を構造化
record SmtpConfig(String host, int port,
String username, String password,
boolean useTls) {}
var config = new SmtpConfig(
"smtp.gmail.com", 587, user, pass, true);
// テキストブロックで HTML 本文を記述
var html = """
<h1>お知らせ</h1>
<p>HTML メールのサンプルです。</p>
""";Library Comparison
注意点
Gmail の SMTP を使う場合、2022年以降はアプリパスワードの生成が必要(通常のパスワードでは認証できない)。二段階認証を有効にしたうえで Google アカウント設定からアプリパスワードを発行する
日本語の件名には message.setSubject(subject, "UTF-8") で文字コードを明示する必要がある。省略すると文字化けの原因になる
STARTTLS(ポート587)と SSL/TLS(ポート465)は設定が異なる。mail.smtp.starttls.enable と mail.smtp.ssl.enable を混同しないこと
開発・テスト環境では Mailtrap や MailHog などのダミー SMTP サーバーを使い、本番メールサーバーへの誤送信を防ぐこと
Jakarta Mail と旧 JavaMail(javax.mail)はパッケージ名が異なる。Jakarta EE 9 以降は jakarta.mail に移行している。依存のバージョンを確認すること
FAQ
Mailtrap や MailHog などのダミー SMTP サーバーを使うのが一般的です。実際のメールボックスに影響を与えず、送信内容をブラウザで確認できます。
Jakarta EE 9 以降でパッケージ名が javax.mail から jakarta.mail に変更されました。API の構造は同じですが、import 文とライブラリ依存の groupId/artifactId が異なります。新規プロジェクトでは jakarta.mail を選んでください。
MimeMultipart に MimeBodyPart を複数追加し、テキスト/HTML パートと添付ファイルパートを組み合わせます。添付パートには DataHandler と FileDataSource を使ってファイルを設定します。