しいしせねっとAmazon.co.jp アソシエイト
[技術資料室] [SMTP] [Java] [J2EE] [java.dev.jp] [developer.jp]

JavaMail のお部屋

Last update 2007.1.14

JavaMail(TM) API こんなんや。トップだけ日本語化されてた。めでたい。
雑誌で時々、簡単に触れられているけど、具体的なのがよく分からないので調べてみましたぞと。

何をするものか

Javaでメールのクライアント(MUA)らしいことが出来る。SMTPで送信ができる。POP3、IMAPもつかえるらしい。
サーバ(MTA)機能は特に持っていない。
よって、メーリングリストなどをつくる場合は、受信部分についてはPOP等を使用するか、別途つくらなければいけないかもしれない。

インストール

J2EEに含まれているものなのでJ2EEで利用する場合はこの設定は不要。Tomcatにも入っている?

JavaBeans Activation Framework (JAF) が必要。面倒ぢゃ・・・。

各種利用する場合

javamailと両方のjarファイルを jre/lib/ext に入れるだけでいいかも。

Tomcatで使う場合

TomcatではServletからだけではなくTomcat自体にJ2EEのjavamail設定ができるようになっているので、共有libディレクトリ(common/lib)にインストールします。

Tomcat 4には最初から入っています。Tomcat 5では、%CATALINA_HOME%/common/lib に mail.jar と activation.jarを入れましょう。

JavaMail のファイルは mail.jar のみでよい。
JREとJDK両方のディレクトリに入れておこう。

必要なもの

java.util.Properties について少々。
[SMTPについて]少々の知識

Tomcat/J2EEの場合は[JNDI]少々

使ってみる

には相当時間がかかりそう・・・
パッケージは javax.mail 以下と、javax.mail.internet

javax.mail.Session と javax.mail.internet.MimeMessageを使用する。

親子構造

Messageをつくるには、まずSession が必要で、Sessionをつくるためのプロパティが必要。
Session を元に Message をつくり、各種設定ができたら、Transport に送信を依頼する。

使う

Message 作ってみるところから?
MessageにはSessionが必要らしい。
Sessionを作るところからか、
SessionにはPropertiesが必要か? ここはまじないみたいなもんかな。

J2SEの場合

Properties property = new Properties();

プロパティできた。

Properties property = System.getProperties();

とする方法もあるが、意味があるのかどうか不明。Systemのプロパティにはjavamailに必要な要素が含まれているのだろうか?

property.setProperty("mail.smtp.host","鯖名");

でいいのか? 謎

property.setProperty("mail.from","Message-IDの素");

MessageIDも正しくするために設定しよう okome@sv1.example.com のようにサーバ名とプロセスやアカウントの名にしてみた。

SMTP-AUTH するときは、次のも必要?

property.setProperty("mail.smtp.auth", "true");

"smtp.auth" では動かなかったというご指摘をいただきました。感謝。m(__ _)m

SMTP用のセッションの準備

Session svSession = Session.getDefaultInstance(property);

ここまで?のSessionは、J2EEではJNDIに設定しておくことができる。Tomcatのconfにも設定項目があります。

J2EEでJNDIを使う場合 (カキカキ中)

JNDIへの登録方法は、各J2EEサーバによって異なる。

まず、J2EEサーバにjavamailのSessionを登録しておく

Tomcat の場合は、web.xml などが適切に設定されていると、Webコンポーネント登録後に各Webコンポーネントに登録用の空JavaMail ができている。あとはadmin 画面で必要な項目を埋めていけばいいかも。

# import javax.naming.*: がされていること

InitialContext context = new InitialContext();
Session svSession = (Session)context.lookup("java:comp/env/MailSession");

J2SE/J2EE共通

MimeMessage message = new MimeMessage(svSession);

やっとメッセージが作れた
送信するのはだあれ?

message.setFrom(new InternetAddress("アドレス","だれそれ名","ISO-2022-JP"));

次受取人・・・

message.setRecipients(MimeMessage.RecipientType.TO, InternetAddress.parse("okome@example.com",false));

日付も入れとこ

message.setSentDate(new java.util.Date());

タイトルは?

message.setSubject("てきとうめーる","iso-2022-jp");

本文は? テキストのみの場合

message.setText("送ってみます。\r\n","iso-2022-jp");
message.setHeader("Content-Transfer-Encoding","7bit");

iso-2022-jpでの送信にはContent-Transfer-Encoding を7bit (または base64) にする必要があります。設定しないとASCII文字でよく使われるquoted-printableになります。また、インターネットの標準改行コードは\r\nなので、UnixやMac OSで使われる\rや\nの省略形になっていないか確認しておきましょう。

添付ファイルがあるときは? setText() のかわりに、こうします。まず本文

MimeMultipart content = new MimeMultipart();
message.setContent(content);
MimeBodyPart text = new MimeBodyPart();
text.setContent("本文だったりします", "text/plain; charset=iso-2022-jp");
text.setHeader("Content-Transfer-Encoding","7bit");
content.addBodyPart(text);

添付付きメールなどで使うMIME形式のメールではquoted-printableは使えませんが、とりあえずこちらでもContent-Transfer-Encodingは7bitに指定。

次に添付ファイル

MimeBodyPart attach = new MimeMultiPart();
FileDataSource fds = new FileDataSource("example.zip");
DataHandler dh = new DataHandler(fds);
attach.setDataHandler(dh);
attach.setFileName("example.zip");
content.addBodyPart(attach);

DataHandlerクラスがOSの情報から適切なMIME Typeなどを設定してくれます。OSに依存しないようにするには独自のDataHandlerを作ったりしてもいいのかも。

おくるぞっ

javax.mail.Transport.send(message);

SMTP-AUTH で送るときはこっち

to が必要?

javax.mail.Transport tp = session.getTransport("smtp");
tp.connect(サーバ名,
ユーザID, パスワード);
InternatAddress[] to = { new InternetAddress("okome@example.com") };
tp.sendMessage( message, 送信先リスト );

POP3/IMAP するには

送信だけではなく、受信にも使えます。メールボックスは、JavaMailではstore と呼ぶようです。APOPは、標準の状態だけでは使えないのかもしれません。APOPが必要なら他のJavaMail のPOP3実装を探しましょう。

Store store = session.getStore("POP3");
store.connect(ホスト, アカウント, パスワード);

Folder inbox;
inbox = store.getFolder("INBOX");
inbox.open(Folder.READ_WRITE);

プロバイダって何?

ここで、JavaMailのページをよく見てみると、なんとかプロバイダというのがいくつかあります。
SMTP、POP3、IMAPといった、普段よくつかうものがあるのですが、これは拡張することもできるようです。

拡張する

JavaMailに新しいプロトコルなどを追加するためには、SPIを使います。

ここでは、SMTP送信用のサーバをそのままJavaMailのプロバイダとして組み込んでしまいましょう。こうすることで、他のサーバが要りません。

参考(まだちゃんと見てないけど・・・)


Amazon.co.jp アソシエイト
しいしせねっと は なんとなくおこめが運営しています。