すべてのプロダクト
Search
ドキュメントセンター

Direct Mail:SMTP の Java 呼び出し例

最終更新日:May 28, 2026

このトピックでは、JavaMail API を使用して簡易メール転送プロトコル (SMTP) 経由でメールを送信する方法について説明します。

次の依存関係を Maven の pom.xml に追加します:

<dependency>
    <groupId>com.sun.mail</groupId>
    <artifactId>javax.mail</artifactId>
    <version>1.6.2</version>
</dependency>
<dependency>
    <groupId>javax.activation</groupId>
    <artifactId>activation</artifactId>
    <version>1.1.1</version>
</dependency>
<dependency>
    <groupId>com.google.code.gson</groupId>
    <artifactId>gson</artifactId>
    <version>2.8.6</version>
</dependency>

接続パラメーター

サンプルコードを実行する前に、次の値を設定します:

パラメーター

備考

SMTP サーバー

smtpdm.aliyun.com

Direct Mail の SMTP エンドポイント

ポート 80 または 25

暗号化なし

デフォルト。ポート 465 がブロックされている場合に使用します。

ポート 465

SSL/TLS

SSLSocketFactory の設定が必要です (サンプルコード内のコメントアウト行をご参照ください)。

ユーザー名

送信元アドレス

Direct Mail コンソールで作成した送信元アドレスです。

パスワード

SMTP パスワード

コンソールで送信元アドレスを作成する際に設定します。

サンプルコード

警告

認証情報をソースコードにハードコードしたり、バージョン管理にコミットしたりしないでください。本番環境では、USER_NAMEPASSWORD を環境変数またはシークレットマネージャーから読み込みます。

次のサンプルでは、JavaMail の MimeMessage API を使用して Direct Mail の SMTP サーバーに対して認証を行い、HTML コンテンツのメールを作成し、Transport.send() を呼び出します。コメントアウトされたセクションでは、オプションの機能として、プレーンテキスト、添付ファイル、SSL、メールトラッキングを示しています。

package org.example;

import javax.mail.*;
import javax.mail.internet.*;
import java.io.UnsupportedEncodingException;
//import java.net.MalformedURLException;
import java.util.Date;
import java.util.Properties;
import java.util.UUID;
//import java.util.HashMap;
//import java.util.Base64;
//import java.net.URL;
//import java.io.IOException;
//import java.io.InputStream;
//import javax.mail.util.ByteArrayDataSource;
//import java.net.URLEncoder;
//import javax.activation.DataHandler;
//import javax.activation.FileDataSource;
//import javax.activation.URLDataSource;

//import com.google.gson.GsonBuilder;

public class SampleMail {
    // 定数を設定します
    private static final String SMTP_HOST = "smtpdm.aliyun.com";
    private static final int SMTP_PORT = 80;
    private static final String USER_NAME = "Sender Address";
    private static final String PASSWORD = "xxxxxxx";

    protected static String genMessageID(String mailFrom) {
        // Message-ID を生成します
        if (!mailFrom.contains("@")) {
            throw new IllegalArgumentException("Invalid email format: " + mailFrom);
        }
        String domain = mailFrom.split("@")[1];
        UUID uuid = UUID.randomUUID();
        return "<" + uuid.toString() + "@" + domain + ">";
    }

    private static void setRecipients(MimeMessage message, Message.RecipientType type, String[] recipients)
            throws MessagingException {
        // 受信者アドレスを設定します
        if (recipients == null || recipients.length == 0) {
            return; // リストが空の場合は設定しません
        }
        InternetAddress[] addresses = new InternetAddress[recipients.length];
        for (int h = 0; h < recipients.length; h++) {
            addresses[h] = new InternetAddress(recipients[h]);
        }
        message.setRecipients(type, addresses);
    }

    public static void main(String[] args) throws MessagingException, UnsupportedEncodingException {
        // メール送信の環境プロパティを設定します
        final Properties props = new Properties();

        // SMTP 経由でメールを送信するには、認証が必要です
        props.put("mail.smtp.auth", "true");
        props.put("mail.smtp.host", SMTP_HOST);
        // ポートを設定します
        props.put("mail.smtp.port", SMTP_PORT);// または "25"。SSL を使用する場合は、ポート 80 または 25 の設定を削除し、次の設定を使用します:
        // 暗号化方式:
        //props.put("mail.smtp.socketFactory.class", "javax.net.ssl.SSLSocketFactory");
        //props.put("mail.smtp.socketFactory.fallback", "false");// 非暗号化接続へのフォールバックを無効にします
        //props.put("mail.smtp.socketFactory.port", "465");
        //props.put("mail.smtp.port", "465");

        props.put("mail.smtp.from", USER_NAME);    // mailfrom パラメーター
        props.put("mail.user", USER_NAME);// 送信者のアカウント (コンソールで作成した送信元アドレス)
        props.put("mail.password", PASSWORD);// 送信元アドレスの SMTP パスワード (コンソールで送信元アドレスのパスワードを設定します)
        //props.put("mail.smtp.connectiontimeout", 1000);
        System.setProperty("mail.mime.splitlongparameters", "false");// 長い添付ファイル名による文字化けの問題を解決します
        //props.setProperty("mail.smtp.ssl.enable", "true");  // ポート 465 と併用します

        // SMTP 認証の認可情報を構築します
        Authenticator authenticator = new Authenticator() {
            @Override
            protected PasswordAuthentication getPasswordAuthentication() {
                return new PasswordAuthentication(USER_NAME, PASSWORD);
            }
        };

        // 環境プロパティと認可情報を使用してメールセッションを作成します
        Session mailSession = Session.getInstance(props, authenticator);

        String messageIDValue = genMessageID(USER_NAME);
        MimeMessage message = new MimeMessage(mailSession) {
            @Override
            protected void updateMessageID() throws MessagingException {
                setHeader("Message-ID", messageIDValue);
            }
        };

        try {
            // 送信者のメールアドレスと表示名を設定します。コンソールで設定した送信元アドレスを使用してください。これは上記の mail.user と同一である必要があります。表示名はカスタマイズ可能です。
            InternetAddress from = new InternetAddress(USER_NAME, "Sender Nickname");// from パラメーター。リレーに使用できます。注:リレーされたメールは、受信者に拒否されるか、迷惑メールフォルダーに移動される可能性が高くなります。
            message.setFrom(from);

            setRecipients(message, Message.RecipientType.TO, new String[]{"recipient_address_1", "recipient_address_2"});
            setRecipients(message, Message.RecipientType.CC, new String[]{"recipient_address_3", "recipient_address_4"});
            setRecipients(message, Message.RecipientType.BCC, new String[]{"recipient_address_5", "recipient_address_6"});

            InternetAddress replyToAddress = new InternetAddress("reply_to_address");
            message.setReplyTo(new Address[]{replyToAddress});// 任意。返信先アドレスを設定します。
            message.setSentDate(new Date());
            message.setSubject("Test Subject");
//            message.setContent("Test TXT content 1", "text/plain;charset=UTF-8");// プレーンテキストのコンテンツ。MimeBodyPart を使用すると上書きされます。
//            または
//            message.setContent("Test<br> HTML content 2", "text/html;charset=UTF-8");// HTML コンテンツ。MimeBodyPart を使用すると上書きされます。

//            // メールトラッキングサービスを有効にするには、次のコードを使用してトラッキングリンクヘッダーを設定します。前提条件と制約については、「データ追跡機能を有効にする方法」のドキュメントをご参照ください。
//            String tagName = "tagname4";
//            HashMap<String, String> trace = new HashMap<>();
//            // 文字列の「1」です
//            trace.put("OpenTrace", "1");      // メール開封トラッキングを有効にします
//            trace.put("LinkTrace", "1");     // メール本文内の URL クリックトラッキングを有効にします
//            trace.put("TagName", tagName);   // コンソールで作成したメールタグ名
//            String jsonTrace = new GsonBuilder().setPrettyPrinting().create().toJson(trace);
//            //System.out.println(jsonTrace);
//            String base64Trace = new String(Base64.getEncoder().encode(jsonTrace.getBytes()));
//            // トラッキングリンクヘッダーを設定します
//            message.addHeader("X-AliDM-Trace", base64Trace);
            // 元のメール (EML) での値の例:X-AliDM-Trace: eyJUYWdOYW1lIjoiVGVzdCIsIk9wZW5UcmFjZSI6IjEiLCJMaW5rVHJhY2UiOiIxIn0=

            // 添付ファイルとコンテンツを送信します:
            // マルチパートメッセージを作成します
            Multipart multipart = new MimeMultipart();

//            // プレーンテキストコンテンツ用の BodyPart を作成します
//            BodyPart textPart = new MimeBodyPart();
//            textPart.setText("Test TXT content 3");
//            multipart.addBodyPart(textPart);

            // HTML コンテンツ用の BodyPart を作成します
            BodyPart htmlPart = new MimeBodyPart();
            htmlPart.setContent("Test<br> HTML content 4", "text/html;charset=UTF-8");// メールコンテンツを設定します。前の message.setContent を上書きします。
            multipart.addBodyPart(htmlPart);

//            // 添付ファイルパート
//            // 添付ファイルを送信します。メールの合計サイズは 15 MB を超えることはできません。メッセージパートを作成します。
//            // ローカルの添付ファイルを送信します
//            String[] fileList = {"C:\\Users\\Downloads\\test1.txt", "C:\\Users\\Downloads\\test2.txt"};
//            for (String filePath : fileList) {
//                MimeBodyPart mimeBodyPart = new MimeBodyPart();
//
//                FileDataSource fileDataSource = new FileDataSource(filePath);
//                mimeBodyPart.setDataHandler(new DataHandler(fileDataSource));
//                // 日本語などの添付ファイル名 (ファイルパスを含む) の文字化けに対処します
//                mimeBodyPart.setFileName(MimeUtility.encodeWord(fileDataSource.getName()));
//                mimeBodyPart.addHeader("Content-Transfer-Encoding", "base64");
//                multipart.addBodyPart(mimeBodyPart);
//            }

//            // URL の添付ファイルを送信します
//            String[] fileListUrl = {"https://example.oss-cn-shanghai.aliyuncs.com/xxxxxxxxxxx1.png", "https://example.oss-cn-shanghai.aliyuncs.com/xxxxxxxxxxx2.png"};
//            for (String fileUrl : fileListUrl) {
//                URL url = new URL(fileUrl);
//                String filename = url.getPath();
//                filename = filename.substring(filename.lastIndexOf('/') + 1);
//                try (InputStream in = url.openStream()) {
//                    // 添付ファイルパートを作成します
//                    MimeBodyPart attachmentPart = new MimeBodyPart();
//                    // バイト配列データソースを使用します
//                    ByteArrayDataSource ds = new ByteArrayDataSource(in, "application/octet-stream");
//                    attachmentPart.setDataHandler(new javax.activation.DataHandler(ds));
//                    attachmentPart.setFileName(filename);
//                    attachmentPart.setDisposition(MimeBodyPart.ATTACHMENT);
//                    multipart.addBodyPart(attachmentPart);
//                } catch (IOException e) {
//                    throw new RuntimeException(e);
//                }
//            }

            // 完全なメッセージを追加します
            message.setContent(multipart);
            // 添付ファイル送信コードの終了

            //mailSession.setDebug(true);// デバッグモードを有効にします
            Transport.send(message);
            System.out.println("送信完了!");
        } catch (MessagingException | UnsupportedEncodingException e) {
            System.err.println("メールの送信に失敗しました: " + e.getMessage());
            e.printStackTrace();
//        } catch (MalformedURLException e) {
//            throw new RuntimeException(e);
        }

    }

}

カスタム SMTP ヘッダー

次のカスタムヘッダーを使用して、メールトラッキングとタグ付けを有効にします。これらのヘッダーを Base64 でエンコードした JSON として message.addHeader() で渡します。前提条件と設定手順については、メールトラッキングのドキュメントをご参照ください。

ヘッダー

キー

説明

X-AliDM-Trace

OpenTrace

"1"

メールの開封イベントを追跡します。

X-AliDM-Trace

LinkTrace

"1"

メール本文内の URL クリックを追跡します。

X-AliDM-Trace

TagName

メールタグ名

メッセージを、コンソールで作成したメールタグに関連付けます。

サンプルコードのコメントアウトされたトラッキングブロックでは、これらのキーを含む JSON オブジェクトを作成し、Base64 でエンコードして、X-AliDM-Trace ヘッダーとして設定します。結果の EML ヘッダーは次のようになります:

X-AliDM-Trace: eyJUYWdOYW1lIjoiVGVzdCIsIk9wZW5UcmFjZSI6IjEiLCJMaW5rVHJhY2UiOiIxIn0=

よくある質問

受信したメールに他の受信者が表示されるのはなぜですか?

これは、SMTP リクエストのメッセージヘッダーに複数のアドレスが指定されている場合に発生します。ユースケースに応じて次の方法を選択してください:

  • 共有スレッド (すべての受信者に表示): 複数の To および CC アドレスを含む 1 つのリクエストを送信します。すべての受信者が互いを確認でき、Message-ID は全員で同一になります。すべての受信者が同じ会話に参加するシナリオに適しています。To と CC を省略して BCC のみを使用することもできますが、推奨しません。一部の受信者の迷惑メール対策ポリシーにより、BCC のみのメッセージが拒否される場合があります。1 リクエストあたりの受信者数の上限については、「制限」をご参照ください。

  • 個別配信 (他の受信者を非表示): 受信者ごとに 1 つのリクエストを送信します。各リクエストにより、通常は異なる Message-ID を持つ別々のメールが生成されるため、どの受信者にも他の受信者は表示されません。たとえば 6 人に送信する場合は 6 回のリクエストが必要です。SMTP は同時リクエストをサポートしているため、これらの呼び出しを並列化できます。