はじめに
Webアプリケーションを構築していると、あるアクションのタイミングでメールを送信したいというケースは多いものです。たとえば、ワークフローシステムであれば、自分の処理を終えて次の人間に処理を回すタイミングで「処理依頼通知」を発信するようにすれば、ユーザはいつもシステムを確認する必要がなくなります。また、フォーラムアプリケーションなどであれば、新規の書き込みがあったタイミングで登録ユーザにメール通知するというのも便利かもしれません。
もちろん、なにからなにまでメールに頼るのも考えものですが、補助的な手段として、メール通知を織り交ぜることで、よりユーザフレンドリーなアプリケーションを構築することができるでしょう。
本稿では、このようなメール通知機能を簡単に実装するためのしくみを紹介します。メール本文をテンプレートとして外部ファイル管理できますので、用途に応じて自由に配信フォーマットをカスタマイズできるのが特長です。
必要な環境
本稿で紹介するメール通知機能は、JSP1.2&サーブレット2.3環境で動作するサーブレットです。利用するにあたっては、以下のソフトウェアが最低限必要となります。これらソフトウェアのインストール方法については、著者サイト「サーバサイド技術の学び舎」より「サーバサイド環境構築設定」を参照してください。
- J2SE 5.0_02
- JSP&サーブレットコンテナ(Tomcat 5.5.7で確認済)
- JavaMail
- JAF(Java Activation Framework)
サンプルコードは「.war」形式で提供しています。記事上部のリンクからダウンロードできる「CZ_MailTransfer.war」を「%CATALINA_HOME%/webapps」フォルダ配下に配置し、コンテナを再起動することで自動的に展開されます。
また、サンプルフォルダ「/CZ_MailTransfer」の直下には、カスタムタグを実際に試すための「sample.jsp」、及び、テスト用のテンプレートとして「/WEB-INF/data」フォルダには「template.dat」が含まれていますので、以下のURLから起動し、コードが正常に動作していることを確認してください。
http://localhost:8080/CZ_MailTransfer/sample.jsp
JavaMail、JAFについては、ダウンロードファイルに既に含まれていますので、サンプルをそのまま利用する場合には改めてインストールする必要はありません。
ファイル構造
先述したように、本稿で紹介するメール通知機能はJSP1.2&サーブレット2.3環境で動作するサーブレットクラスです。まずは、ダウンロードファイル内のファイル構造を示しておきます(赤字のファイルは、他のアプリケーションで利用する場合に必要なファイルであることを表します)。
MailTransferサーブレットの利用方法
MailTransferサーブレットでは、その動作を以下の3箇所で規定しています。使用するにあたっては、適宜、必要なパラメータを変更した上で利用してください。
- デプロイメントディスクリプタ
- メール本文のテンプレート
- JSPページから送信されるポストデータ
smtp
」パラメータ(メール送信時に利用するSMTPサーバ名)を要求します。サンプルではダミーのサーバ名がセットされていますので(太字部分)、使用時には適宜、利用可能なサーバ名に差し替えてください。<servlet> <servlet-name>MailTransfer</servlet-name> <servlet-class>to.msn.wings.codezine.MailTransfer </servlet-class> <init-param> <param-name>smtp</param-name> <param-value>''smtp.xxxxx.ne.jp''</param-value> </init-param> </servlet>
■■__name__様にメッセージが届いています■■ ---------------------------------------------------------------- メッセージ: __message__ ----------------------------------------------------------------
要素名 | 概要 |
_to | メール送信の宛先 |
_from | メールの送信元アドレス |
_fromArias | メールの送信者名 |
_subject | メールの件名 |
_location | メール送信後の遷移先URL |
以上の規則に従って、記述した「sample.jsp」は以下の通りです。なお、<form>
タグのaction
オプションは固定値で「MailTransfer」(MailTransferサーブレットのURLパターン)とする必要があります(下記、太字部分)。
<%@ page contentType="text/html;charset=Windows-31J" %> <form method="POST" action="''MailTransfer''"> <input type="hidden" name="_from" value="CQW15204@nifty.com" /> <input type="hidden" name="_fromArias" value="山田祥寛" /> <input type="hidden" name="_location" value="sample.jsp" /> <input type="hidden" name="_subject" value="サンプルテスト" /> 送信先名:<input type="text" name="name" size="30" /><br /> 送信先アドレス:<input type="text" name="_to" size="50" /><br /> メッセージ:<input type="text" name="message" size="100" /><br /> <input type="submit" value="メール送信" /> </form>
なお、本サンプルでは_to
パラメータを隠しフィールドで指定していますが、隠しフィールドは悪意ある第3者が簡単に改竄することができます。実際に利用するに際しては、送信可能なメールアドレスをあらかじめ使用者に登録させ、サーバ側で存在チェックを行うなど、アドレスの妥当性検証は最低限行うようにしてください。
サーブレットクラスMailTransferの構造
サーブレットクラスMailTransferの使い方を理解したところで、MailTransferそのものの構造を覗いてみることにしましょう。なお、本稿ではサーブレットに関する基本的な規則については詳述しません。興味のある方は、拙稿「基礎から学ぶサーブレット/JSP(@IT)」などの記事を参照してください。
request.setCharacterEncoding("Windows-31J"); ServletConfig config=this.getServletConfig(); ServletContext application=config.getServletContext(); // 必要なパラメータを設定した上で、メールセッションを確立 Properties objPrp=new Properties(); objPrp.put("mail.smtp.host",config.getInitParameter("smtp")); objPrp.put("mail.host",config.getInitParameter("smtp")); Session session=Session.getDefaultInstance(objPrp,null); // メール本体を生成(宛先、送信元、件名、本文をセット) MimeMessage msg=new MimeMessage(session); try { msg.setRecipients(Message.RecipientType.TO, request.getParameter("_to")); InternetAddress objFrm=new InternetAddress( request.getParameter("_from"),request.getParameter("_fromArias")); msg.setFrom(objFrm); msg.setSubject(request.getParameter("_subject"),"ISO-2022-JP"); // テンプレートファイルを読み込み、ポストデータと照合しながら // メール本文を生成 StringBuffer body=new StringBuffer(); BufferedReader template=new BufferedReader( new FileReader(application.getRealPath( "/WEB-INF/data/template.dat"))); while(template.ready()){body.append(template.readLine() + "\r\n");} String bodyText=body.toString(); Enumeration objEnm=request.getParameterNames(); while(objEnm.hasMoreElements()){ String name=(String)objEnm.nextElement(); if(!name.startsWith("_")){ bodyText=bodyText.replaceAll("__" + name + "__",request.getParameter(name)); } } template.close(); msg.setText(bodyText,"ISO-2022-JP"); // メール送信を実行 Transport.send(msg); // 処理後は指定されたページにリダイレクト response.sendRedirect(request.getParameter("_location"));
MailTransferに関する大まかな処理の流れは、コード中のコメントを読んでいただくとして、JavaMailでメール送信を行う場合に注意しなければならないのは、以下の2点です。
mail.host
、mail.smtp.host
パラメータは双方指定- マルチバイト文字を含む場合は「ISO-2022-JP」で送信
mail.smtp.host
プロパティを指定するだけでもメールは正常に送信できます。しかし、mail.host
プロパティは内部的にMessage-IDヘッダを利用するために利用されるパラメータ値です。mail.host
プロパティが省略された場合、Message-IDプロパティが正常に生成されませんので、注意してください。mail.host
、mail.smtp.host
プロパティは原則として双方省略せずに送信するべきです。まとめ
以上、JSP&サーブレットアプリケーションで利用可能なMailTransferサーブレットを紹介してみました。本稿ではまず基本的な機能を実装してみましたが、「HTMLメールや添付ファイルにも対応したい」「複数人に同報配信したい」など、さまざまなニーズにも対応してみると面白そうです。
関連リンク
- @IT 『Java Solution 連載記事「基礎から学ぶサーブレット/JSP」』 山田祥寛 著