ozacc-mail library - メールの送信方法
Author: Tomohiro Otsuka

ozacc-mail library

##### Project Documentation

- About ozacc-mail library
- Project Info
- Project Reports
- Development Process

## メールの送信方法

ozacc-mail libraryは、Spring FrameworkやSeasar2といったDIコンテナに組み込んで使用できるメール送信ライブラリです。DIコンテナ上での使用を想定していますが、DIコンテナ環境外での使用も可能です。

## SendMail 使用方法 with Spring

`SendMail`は、JavaMail APIをラップし、メール送信のための至極シンプルなインターフェースを提供しています。提供しているメソッド名はたった一つ、`send()`です。メールデータを表す`com.ozacc.mail.Mail`インスタンスか、JavaMailの`MimeMessage`インスタンスを引数に指定すると、それを送信します。(これらの配列も指定可能です。)

`SendMail(SendMailImpl).send()`メソッドは、スレッドセーフな設計になっていますが、呼び出すスレッドの数だけSMTPサーバに接続します。通常の使用では問題にならないはずですが、メールサーバやその設定によっては注意が必要です。

`SendMail`の使用方法を、Springと連携させる場合を例にとって説明します。

▼applicationContext.xmlでのBean定義

    <beans>
        <bean id="sendMail" class="com.ozacc.mail.impl.SendMailImpl">
            <!-- SMTPサーバ -->
            <property name="host"><value>smtp.example.com</value></property>
        </bean>
    </beans>

▼Javaソース

    // Mailインスタンスの生成
    Mail mail = new Mail();
    mail.setFrom("shop@example.com", "XXXオンラインショップ");
    mail.addTo("misaki@foo.com", "伊東美咲さま");
    mail.addBcc("order@example.com");
    mail.setSubject("ご注文の確認");
    mail.setText("お買い上げありがとうございました。\n\nご注文明細・・・");

    // SendMailインスタンスの取得
    SendMail sendMail = (SendMail)applicationContext.getBean("sendMail");

    // メールの送信
    sendMail.send(mail);

`sendMail.send(mail)`で、何らかの原因で送信に失敗すると、`com.ozacc.mail.MailException`がスローされます。`MailException`は非チェック例外なので、プログラムの要求に応じてキャッチしてください。

## MailBuilder 使用方法 with Spring

`MailBuilder`を使用すると、ファイルに記述されたメールデータから`Mail`インスタンスを生成できます。
さらに、`MailBuilder`インターフェースを継承した`VelocityMailBuilder`を使用すると、`Velocity`と連携して動的にメールデータを生成し、そのデータからMailインスタンスを生成できます。

現バージョンでは、XML形式のメールデータを扱う`XMLMailBuilderImpl`クラスが提供されています。ここではその使用方法を、Springと連携させる場合を例にとって説明します。

▼applicationContext.xmlでのBean定義

    <beans>
        <bean id="sendMail" class="com.ozacc.mail.impl.SendMailImpl">
            <property name="host"><value>smtp.example.com</value></property>
        </bean>

        <bean id="mailBuilder" class="com.ozacc.mail.impl.XMLMailBuilderImpl" />
    </beans>

▼Javaソース

    // MailBuilderインスタンスの取得
    MailBuilder mailBuilder = (MailBuilder)applicationContext.getBean("mailBuilder");

    // メールデータXMLファイルのパス (クラスパス上)
    String path = "/com/example/mail/mail-template.xml";

    // Mailインスタンスを生成
    Mail mail = mailBuilder.buildMail(path);

    // SendMailインスタンスの取得
    SendMail sendMail = (SendMail)applicationContext.getBean("sendMail");

    // メールの送信
    sendMail.send(mail);

▼mail-template.xml

    <?xml version="1.0" encoding="utf-8" ?>
    <!DOCTYPE mail PUBLIC "-//OZACC//DTD MAIL//EN" "http://www.ozacc.com/library/dtd/ozacc-mail.dtd">

    <mail>

        <returnPath email="return@example.com" />

        <from email="from@example.com" name="差出人" />

        <recipients>
            <to email="to1@example.com" name="宛先1" />
            <cc email="cc1@example.com" name="CC1" />
            <bcc email="bcc@example.com" />
            <cc email="cc2@example.com" />
            <to email="to2@example.com" />
        </recipients>

        <replyTo email="reply@example.com" />

        <!-- subject(件名)の前後のホワイトスペース(半角スペース、タブ、改行)は削除されます。 -->
        <subject>
            件名
        </subject>

        <!-- body(本文)の前後のホワイトスペース(半角スペース、タブ、改行)は削除されます。 -->
        <body>
            本文
        </body>

    </mail>

DTDで定義されているように、ルート要素`<mail>`以外の全要素はオプションです。
例えば`<from>`要素だけ含んだXMLからは、`from`プロパティだけセットされたMailインスタンスが生成されます。

Velocityとの連携については、テストケース(`src/test/com/ozacc/mail/impl/XMLVelocityMailBuilderImplTest`)を参照してください。

## XMLMailFactoryBean 使用方法

`XMLMailFactoryBean`はSpringと連携している場合にのみ使用可能です。

上述した`MailBuilder`を使ってXMLメールデータから`Mail`インスタンスを生成する場合、XMLファイルのロケーションを示すパスがソース内にハードコーディングされています。一般的にはアプリケーション側で、`MailBuilder`のインスタンスとXMLファイルのロケーションパスをプロパティとして保持するクラスを作り、DIコンテナでプロパティを設定するようにします。
Springを使用している場合、このようなクラスを作らずともXMLファイルのロケーションパスをソースから追い出し、コンテナ上でMailインスタンスを生成させることができます。

▼applicationContext.xmlでのBean定義

    <beans>
        <bean id="sendMail" class="com.ozacc.mail.impl.SendMailImpl">
            <property name="host"><value>smtp.example.com</value></property>
        </bean>

        <bean id="mail" class="com.ozacc.mail.spring.XMLMailFactoryBean">
            <!-- メールデータXMLファイルのパス (クラスパス上) -->
            <property name="classPath"><value>/com/example/mail/mail-template.xml</value></property>
        </bean>
    </beans>

▼Javaソース

    // Mailインスタンスの生成、取得
    Mail mail = (Mail)applicationContext.getBean("mail");

    // SendMailインスタンスの取得
    SendMail sendMail = (SendMail)applicationContext.getBean("sendMail");

    // メールの送信
    sendMail.send(mail);

`XMLMailFactoryBean`から生成される`Mail`インスタンスは、`prototype`です。つまりシングルトンではなく、呼び出すたびに新しい`Mail`インスタンスが生成されます。何かの理由で`Mail`インスタンスをシングルトンにしたい場合は、`XMLMailFactoryBean`の`singlton`プロパティに`true`をセットするだけです。

`XMLMailFactoryBean`では、Velocityと連携させて`Mail`インスタンスを生成することはできません。