...

JavaMailについての記事では

by user

on
Category: Documents
8

views

Report

Comments

Transcript

JavaMailについての記事では
//from the vault /
Java EEでJavaMailを使う
メールを送れるWebアプリケーションの作成
T. LAMINE BA
本
必要なソフトウェア
ケーションには、3 つの Web ページが含まれます。それぞれトップ・ページ、
「送
Windows 7)、Java EE 6 以降の JDK、IDE(本記事では NetBeans 7)、GlassFish
信完了」の確認ページ、
「送信失敗」の通知ページです。
や Apache Tomcat などの Web サーバーを使用します。
記事では、コア JavaMail API を利用して電子メールを送信する、シンプル
な Web アプリケーションを作成する方法について説明します。このアプリ
Web アプリケーションのトップ・ページ(図 1 参照)には、送信者と受信者の
このチュートリアルでは、ソフトウェアとして Microsoft Windows(本記事では
電子メール・アドレスの入力フィールド、件名と本文の入力フィールド、SMTP サー
バーに関連するいくつかのフィールド(IP アドレス、ユーザー名、パスワード、ポー
ト番号)という Web コンポーネントが含まれています。もちろん、重要な「送信」
ボタンもあります。
確認ページ
(図 2 参照)とそれに似た送信成功通知ページには、ユーザーがトッ
プ・ページに戻るためのボタンのみが必要です。
JavaMail API
JavaMail API は、電子メッセージの読取り、作成、送信などの一般的な電子メー
ル機能を提供するパッケージです。JavaMail はプラットフォーム非依存、プロト
コル非依存のフレームワークであり、Java EE に含まれています。
図 3 に示すとおり、JavaMail には、アプリケーション・コンポーネントが電子メー
ルの送受信に使用する、アプリケーション・レベルのインタフェースがあります。
また、プロトコル固有の処理に対応するサービス・プロバイダ(SP)インタフェー
スもあります。たとえば、SMTP は電子メールの送信に使用されるプロトコルです。
Post Office Protocol 3(POP3)は、電子メール受信用プロトコルの標準になって
図1:電子メール・アプリのメイン・ページ
います。Internet Message Access Protocol(IMAP)は、POP3 の代わりに使用
できます。
さらに、JavaMail API には JavaBeans Activation Framework(JAF)が含まれ
ており、Multipurpose Internet Mail Extensions(MIME)、URL、添付ファイルな
ど、プレーンなテキスト以外の電子メール・コンテンツを扱えます。
図2:確認ページ
ORACLE.COM/JAVAMAGAZINE /////////////////////////////// JULY/AUGUST 2016
25
//from the vault /
POP3
mail store
SMTP
Server
なるgetterメソッドとsetterメソッドを作成します。受信者の電子メール・ア
ドレスがString型のtoという変数だとすると、getterメソッドとsetterメソッ
ドの定義方法はリスト1のようになります。
IMAP
mail store
JavaMail
POP3
SP
SMTP
SP
package useJavaMail;
/*** すべての必要なライブラリのインポート ***/
IMAP
SP
JavaMail API
リスト1:
JAF
Java Application
図3: JavaMail APIの設計
方法
@ManagedBean
@RequestScoped
public class emailJSFManagedBean {
private String to;
/** emailJSFManagedBeanの新しいインスタンスの作成 */
public emailJSFManagedBean() {
to = null;
}
このチュートリアルではJavaServer Faces(JSF)テクノロジーを利用して
Webアプリケーションを作成します。そのため、次のワークフローで進める
ことにします。
1. バッキングBeanを作成する
2. コンポーネント・タグを使用してWebページを作成する
3. FacesServletインスタンスをマッピングする
手順1:バッキングBeanを作成する
バッキングBeanは、JSFテクノロジー固有のマネージドBeanの一種で
す。Webアプリケーションのロジックを格納しており、Webページに含まれ
るWebコンポーネントとやり取りします。バッキングBeanには、それぞれの
Webコンポーネントに対応するprivate属性、その属性に対応するgetterメソ
ッドとsetterメソッド、さらに次の4つのタスクを処理するメソッドを含める
ことができます。
■■ Webページ間のナビゲーションに関連する処理を実行する
■■ アクション・イベントを処理する
■■ コンポーネントの値を検証する
■■ 値変更イベントを処理する
これに従い、emailJSFManagedBeanというバッキングBeanの中に、本
記事の最初の方に記載した8つのWebコンポーネントのそれぞれに必要と
ORACLE.COM/JAVAMAGAZINE /////////////////////////////// JULY/AUGUST 2016
public String getTo() {
return to;
}
public void setTo(String to) {
this.to = to;
}
}
このコードの @ManagedBeanは、バッキングBeanをリソースとしてJSF
実装に登録するための宣言です。また、@RequestScopedは、このマネー
ジドBeanがリクエストのスコープでのみリソースとして存在することを示す
アノテーションです。つまり、このBeanは、ユーザーがWebアプリケーション
とやり取りするための1回のHTTPリクエストの期間だけ存在します。
このバッキングBeanでは、さらに2つのメソッドを作成します。.
1つ目のメソッドの役割は、ユーザーがWebアプリケーションで送信した
すべての電子メールを検証することです(リスト2参照)。
26
//from the vault /
リスト2:
public void validateEmail(FacesContext context,
UIComponent toValidate, Object value) {
String message = "";
String email = (String) value;
if(email == null ¦¦ email.equals("")) {
((UIInput)toValidate).setValid(false);
message = "E-mail address is required";
context.addMessage(
toValidate.getClientId(context),
new FacesMessage(message));
}
else if (!(email.contains("@") &&
email.contains("."))) {
((UIInput)toValidate).setValid(false);
message = "E-mail address is invalid";
context.addMessage(
toValidate.getClientId(context),
new FacesMessage(message));
}
}
この電子メール検証メソッドは、次の3つの引数をとります。
■■ JSF実装のコンテキスト
:マネージドBeanからユーザー・インタフェースに
エラー・メッセージを渡すためのものです。
■■ このメソッドを呼び出すWebコンポーネントの識別子である
UIComponent toValidate:この例でのWebコンポーネントは、ユー
ザー入力を引数として受け取るテキスト入力フィールドのメソッドです(リ
スト1参照)。ユーザー入力については図1を参照してください。
■■ value変数:検証する必要のある電子メール・
アドレスを格納します。
したがって、リスト2に示すコードは、次のタスクを実行します。
■■ Webコンポーネントのローカル値を取得する
■■ 値がnullや空であるかどうかをチェックする
ORACLE.COM/JAVAMAGAZINE /////////////////////////////// JULY/AUGUST 2016
値がnullまたは空の場合は、コンポーネントのvalidプロパティの値を
falseに設定し、エラー・メッセージを「E-mail address is required」
に設定する
■■ そうでない場合は、
「@」とピリオド(「.」)が値に含まれているかどうか
をチェックする
■■ 含まれていない場合は、
コンポーネントのvalidプロパティの値を
falseに設定し、エラー・メッセージを「E-mail address is invalid」に
設定する
エラー・メッセージは、FacesContextインスタンスに送られ、それによって
呼出し元のWebコンポーネントに関連付けられます。
2つ目のメソッドは、JavaMailを利用して電子メールを送信するロジック
を扱います。このナビゲーション処理メソッドは、
「SEND E-MAIL」ボタンの
クリックというアクションによってトリガーされます(リスト3参照)。
■■
リスト3:
public String submitEmail() {
// 電子メールの作成と送信
/*** 変数の初期化 ***/
props = new Properties();
// propsにセッションとメッセージ・データを設定
session = Session.getDefaultInstance(
props, null);
message = new MimeMessage(session);
try {
message.setContent(this.getDescr(),
"text/plain");
message.setSubject(this.getSubject());
fromAddress =
new InternetAddress(this.getFrom());
message.setFrom(fromAddress);
toAddress =
new InternetAddress(this.getTo());
message.setRecipient(RecipientType.TO,
toAddress);
// メッセージの転送
27
//from the vault /
message.saveChanges(); //送信のためには保存が必要
Transport transport =
session.getTransport("smtp");
transport.connect(this.smtp, this.port,
this.username,
this.password);
if(transport.isConnected() == false)
return "b_response";
transport.sendMessage(
message, message.getAllRecipients());
transport.close();
}
catch (MessagingException me) {
// 例外処理
return "b_response";
}
return "g_response";
}
このようなタイプのメソッドを、アクション・メソッドといいます。このメソッ
ドは、引数をとらないpublicメソッドであり、Webアプリケーションで移動
先となるページを表す文字列を返します。この例では、このメソッドで電子
メールを生成して送信します。電子メールの送信が成功した場合、このメソ
ッドはg_response(「good response」の略)を返し、その結果、ブラウ
ザでg_response.xhtmlページが表示されます(図2参照)。電子メールの
送信が失敗した場合は、b_response(「bad response」の略)を返し、
ブラウザではb_response.xhtmlページが表示されます。.
JavaMailを利用して電子メールを送信するためには、まずSessionク
ラスの電子メール・セッション・インスタンスを初期化します。この電
子メール・セッションがJavaMailの起点となります。このメソッドで
は、java.util.Propertiesクラスを使用して、電子メール・サーバー、ユーザ
ー名、パスワードなどの情報を取得します。これらの情報は、アプリケーシ
ョン全体で共有できます。この例では、次のようにして、Sessionクラスの
デフォルト・インスタンスを作成します。
ORACLE.COM/JAVAMAGAZINE /////////////////////////////// JULY/AUGUST 2016
session =
Session.getDefaultInstance(props, null);
次に、作成したセッションを用いて、Messageクラスの電子メールを生成
します。ただし、Messageは抽象クラスであるため、代わりにサブクラスの
MimeMessageを使用します。このクラスのメッセージでは、さまざまな
標準を規定したRFCで定義されているMIMEタイプとヘッダーを利用できま
す。次のように、
セッションを引数としてメッセージを作成します。
MimeMessage message =
new MimeMessage(session)
電子メールを送信するためには、Transport型のオブジェクトを操作しま
す。メッセージは、SMTP転送プロトコルを使用して送信します。Transport
クラスが送信を処理します。次のようにしてオブジェクトをインスタンス化
します。
Transport transport =
session.getTransport("smtp");
このトランスポート・オブジェクトが、指定された認証情報(SMTPサーバー
のアドレス、SMTP接続を受け付けるポート番号、ユーザー名、パスワード)
を使用し、SMTPサーバーへの接続を試みます。
transport.connect(this.smtp,
this.port, this.username,
this.password);
SMTPサーバーが接続を許可したら、sendコマンドを用いて電子メールが
送信されます。
最後に、closeコマンドを呼び出して、トランスポート・サービスをクロー
ズします。
transport. sendMessage(message,
message.getAllRecipients());
transport.close();
28
//from the vault /
NこのバッキングBeanを含むファイルは、WebアプリケーションのSources
Packagesディレクトリの下に配置する必要がある点に注意してください。
手順2:コンポーネント・タグを使用してWebページを作成
する
このアプリケーションのそれぞれのWebページでは、Facelets宣言言語を
活用することで、さまざまなWebコンポーネントのためのタグを生成しま
す。
トップ・ページを作成します。このページ(図1参照)では、Web
コンポーネントに関連するタグとして、inputText、inputSecre
t、inputTextArea,、commandButtonの4種類を使用します。
inputTextは、HTMLでtypeがtextであるinputタグに相当します。つまり、
これもユーザー入力を受け付けるフィールドです。この例では、送信者の
アドレス、受信者のアドレス、電子メールの件名、SMTPサーバーのアドレ
ス、SMTPサーバーのユーザー名、SMTPサーバーのポート番号を取得するた
めに、このタグを利用します。
inputSecretは、HTMLでpasswordであるinputタグに相当します。こ
れもユーザー入力を受け付けるフィールドです。ただし、inputSecretは、
inputTextタグとは異なり、ユーザーが入力した値を表示しません。SMTP
サーバーのパスワードを取得するために、このタグを使用します。
inputTextAreaは、HTMLのtextareaタグに相当します。送信する電子
メールの本文を取得するために、このタグを使用します。
このアプリケーションでは、標準バリデータを利用するか、バッキング
Beanに実装した検証メソッドを呼び出して、ユーザー入力を検証します(リ
スト2参照)。
たとえば、リスト4に示すコードを使用した「FROM」アドレス・フィールド
では、Faceletsを利用してemailJSFManagedBean.validateEmail検証
メソッドを呼び出します。
リスト4:
<h:form>
<table>
<tr>
<th style="width:100px"
align="right">FROM:</th>
ORACLE.COM/JAVAMAGAZINE /////////////////////////////// JULY/AUGUST 2016
<td>
<h:inputText id="from" size="100"
validator=
"#{emailJSFManagedBean.validateEmail}"
value="#{emailJSFManagedBean.from}" />
<span style="margin-left:10px">
<h:message style="color:red" for="from"/>
</span>
</td>
</tr>
</table>
</form>
なお、messageタグ(<h:message/>)の目的は、電子メール・アドレスが
検証されなかったときにエラー・メッセージを表示することです。
別の例として、
「SUBJECT」フィールドでは、リスト5に示すように、Facelets
の標準バリデータを利用しています。
リスト5:
<h:form>
<table>
<tr>
<th style="width:100px" align="right">FROM:</th>
<td>
<h:inputText id="subject" size="100"
validatorMessage="Subject is required"
value="#{emailJSFManagedBean.subject}">
<f:validateRequired for="subject"/>
</h:inputText>
<span style="margin-left:10px">
<h:message style="color:red" for="from"/>
</span>
</td>
</tr>
</table>
</form>
29
//from the vault /
idがsubjectであるinputTextに対してvalidateRequired タグ
(<f:validateRequired/>)を適用しています。これにより、
「SUBJECT」
</servlet-mapping>
フィールドが空で、フォームが送信された場合、フォームが無効になります。
この例では、messageタグ(<h:message/>)がある場所にエラー・メッセ
ージが表示されます。
なお、NetBeansなどのIDEを使用していれば、このマッピングは自動的に行
われます。
今回の例では、JavaMail APIの基本的な機能の使用方法のみを紹介
しました。しかし、このライブラリはさまざまな拡張が可能で、メール・
エージェントに関するほぼすべてのニーズに対応できるようになっていま
す。JavaMailはJava EEで使用するために設計されたものですが、Java SEで
も使うことができます。JavaMailによってプロジェクトがもっと楽しくなるこ
とでしょう。
確認ページとエラー通知ページを作成します。T確認ペ
ージ(g_response.xhtml)は、電子メールが送信されたときに呼び出
されます(図2参照)。一方、エラー通知ページ(b_response.xhtml)
は、電子メールが送信できなかった場合に呼び出されます。いずれ
のページでも、FaceletsによるWebコンポーネントは、次のような
commandButton タグがそれぞれに1つだけ含まれます。
<h:form>
<h:commandButton id="back"
value="Back" action="index">
</h:form>
【編集注://from the vault /シリーズの記事は、過去のJava Magazine
に掲載された記事を更新したもので、本記事もそれに該当します。本記事
は、2012年3月/4月号に初めて掲載されました】</article>
T. Lamine Ba:Real Basisの社長で、西アフリカのJavaユーザー・
グループSeneJUGの共同設立者。JUG-Africaの初期メンバーの1
人。
このコードが生成するボタンをユーザーがクリックすると、トップ・ページ
(index.xhtml)に戻ります。
手順3:FacesServletインスタンスをマッピングする
最後の手順として、Webデプロイメント・ディスクリプタであるweb.xmlファ
イルを編集し、FacesServletインスタンスをマッピングします。リスト6に
一般的な例を示します。
リスト6:
<servlet>
<servlet-name>Faces Servlet</servlet-name>
<servlet-class>
javax.faces.webapp.FacesServlet</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>Faces Servlet</servlet-name>
<url-pattern>/faces/*</url-pattern>
ORACLE.COM/JAVAMAGAZINE /////////////////////////////// JULY/AUGUST 2016
30
Fly UP