Shoeisha Technology Media

CodeZine(コードジン)

特集ページ一覧

自由形式のフォームから投函された内容をメール送信する

Webアプリケーションにおけるメール通知機能の実装

  • LINEで送る
  • このエントリーをはてなブックマークに追加
2005/03/28 00:00

あるアクションのタイミングでメールを送信したいWebアプリケーションで、メール通知機能を簡単に実装するためのしくみを紹介します。

はじめに

 Webアプリケーションを構築していると、あるアクションのタイミングでメールを送信したいというケースは多いものです。たとえば、ワークフローシステムであれば、自分の処理を終えて次の人間に処理を回すタイミングで「処理依頼通知」を発信するようにすれば、ユーザはいつもシステムを確認する必要がなくなります。また、フォーラムアプリケーションなどであれば、新規の書き込みがあったタイミングで登録ユーザにメール通知するというのも便利かもしれません。

 もちろん、なにからなにまでメールに頼るのも考えものですが、補助的な手段として、メール通知を織り交ぜることで、よりユーザフレンドリーなアプリケーションを構築することができるでしょう。

 本稿では、このようなメール通知機能を簡単に実装するためのしくみを紹介します。メール本文をテンプレートとして外部ファイル管理できますので、用途に応じて自由に配信フォーマットをカスタマイズできるのが特長です。

必要な環境

 本稿で紹介するメール通知機能は、JSP1.2&サーブレット2.3環境で動作するサーブレットです。利用するにあたっては、以下のソフトウェアが最低限必要となります。これらソフトウェアのインストール方法については、著者サイト「サーバサイド技術の学び舎」より「サーバサイド環境構築設定」を参照してください。

 サンプルコードは「.war」形式で提供しています。記事上部のリンクからダウンロードできる「CZ_MailTransfer.war」を「%CATALINA_HOME%/webapps」フォルダ配下に配置し、コンテナを再起動することで自動的に展開されます。

 また、サンプルフォルダ「/CZ_MailTransfer」の直下には、カスタムタグを実際に試すための「sample.jsp」、及び、テスト用のテンプレートとして「/WEB-INF/data」フォルダには「template.dat」が含まれていますので、以下のURLから起動し、コードが正常に動作していることを確認してください。

http://localhost:8080/CZ_MailTransfer/sample.jsp
「sample.jsp」の入力内容をテンプレート「template.dat」で整形した上でメール配信
「sample.jsp」の入力内容をテンプレート「template.dat」で整形した上でメール配信

 JavaMail、JAFについては、ダウンロードファイルに既に含まれていますので、サンプルをそのまま利用する場合には改めてインストールする必要はありません。

ファイル構造

 先述したように、本稿で紹介するメール通知機能はJSP1.2&サーブレット2.3環境で動作するサーブレットクラスです。まずは、ダウンロードファイル内のファイル構造を示しておきます(赤字のファイルは、他のアプリケーションで利用する場合に必要なファイルであることを表します)。

ダウンロードファイル内のファイル構造
ダウンロードファイル内のファイル構造

MailTransferサーブレットの利用方法

 MailTransferサーブレットでは、その動作を以下の3箇所で規定しています。使用するにあたっては、適宜、必要なパラメータを変更した上で利用してください。

  1. デプロイメントディスクリプタ
  2. MailTransferサーブレットは、初期化パラメータとして「smtp」パラメータ(メール送信時に利用するSMTPサーバ名)を要求します。サンプルではダミーのサーバ名がセットされていますので(太字部分)、使用時には適宜、利用可能なサーバ名に差し替えてください。
    「web.xml」 (抜粋)
    <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>
    
  3. メール本文のテンプレート
  4. MailTransferサーブレットは、メール送信時にあらかじめ用意されたテンプレートをもとにメール本文を生成します。テンプレートには「__パラメータ名__」の形式で変数を指定できるのが特長です。「__パラメータ名__」はクライアントから送信されたポストデータの内容によって置き換えられます。
    以下は、ダウンロードファイルに含まれているサンプルのテンプレートです。テンプレートは、必ずアプリケーションルート直下の「/WEB-INF/data」フォルダに「template.dat」という名前で配置する必要があります。
    「template.dat」
    ■■__name__様にメッセージが届いています■■
    ----------------------------------------------------------------
    メッセージ:
    __message__
    ----------------------------------------------------------------
    
  5. JSPページから送信されるポストデータ
  6. 最後に、MailTransferサーブレットは、メール送信時に必要な情報をJSPページからのポストデータによって受け取ります。フォーム要素名は一般的なHTMLのルールに従ってさえいれば自由に命名できますが、唯一、先頭が「_(アンダースコア)」で始まる要素名はMailTransferサーブレットでは予約要素と見なされ無視されますので、注意してください。なお、以下にMailTransferサーブレットで利用可能な予約要素を一覧に示しておきます。
    MailTransferサーブレットの予約要素
    要素名概要
    _toメール送信の宛先
    _fromメールの送信元アドレス
    _fromAriasメールの送信者名
    _subjectメールの件名
    _locationメール送信後の遷移先URL

 以上の規則に従って、記述した「sample.jsp」は以下の通りです。なお、<form>タグのactionオプションは固定値で「MailTransfer」(MailTransferサーブレットのURLパターン)とする必要があります(下記、太字部分)。

「sample.jsp」
<%@ 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)」などの記事を参照してください。

「MailTransfer.java」 (抜粋)
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点です。

  1. mail.hostmail.smtp.hostパラメータは双方指定
  2. 単にメールを送信するだけならば、mail.smtp.hostプロパティを指定するだけでもメールは正常に送信できます。しかし、mail.hostプロパティは内部的にMessage-IDヘッダを利用するために利用されるパラメータ値です。mail.hostプロパティが省略された場合、Message-IDプロパティが正常に生成されませんので、注意してください。mail.hostmail.smtp.hostプロパティは原則として双方省略せずに送信するべきです。
  3. マルチバイト文字を含む場合は「ISO-2022-JP」で送信
  4. 件名やメール本文にマルチバイト文字を含む場合には、必ず文字エンコーディング名を明示的に指定する必要があります。メールで一般的に利用される文字エンコーディングは「ISO-2022-JP」です。

まとめ

 以上、JSP&サーブレットアプリケーションで利用可能なMailTransferサーブレットを紹介してみました。本稿ではまず基本的な機能を実装してみましたが、「HTMLメールや添付ファイルにも対応したい」「複数人に同報配信したい」など、さまざまなニーズにも対応してみると面白そうです。

関連リンク

  1. @IT 『Java Solution 連載記事「基礎から学ぶサーブレット/JSP」』 山田祥寛 著
  • LINEで送る
  • このエントリーをはてなブックマークに追加

修正履歴

  • 2005/04/15 12:16 セキュリティ部分について追記

著者プロフィール

  • 山田 祥寛(ヤマダ ヨシヒロ)

    静岡県榛原町生まれ。一橋大学経済学部卒業後、NECにてシステム企画業務に携わるが、2003年4月に念願かなってフリーライターに転身。Microsoft MVP for ASP/ASP.NET。執筆コミュニティ「WINGSプロジェクト」代表。 主な著書に「入門シリーズ(サーバサイドAjax/XMLD...

All contents copyright © 2005-2018 Shoeisha Co., Ltd. All rights reserved. ver.1.5