Servletでメール処理

受信したメールをサーブレットやJSPで処理できると他処理との連携が容易になる場合があります。以下にその方法のサンプルを記載します。(エラー処理などは省略しています)

受信メールを受け取るアカウントのホームで .forward ファイルを作成します。(この例ではアカウントを inmail 、ホームを /home/inmail とします)

"| /home/inmail/mp.sh || exit 75"

mp.sh を作成します。ここでは w3m を使用しますので、インストールされていることを確認してください。

#!/bin/sh
 
datdir=/home/inmail
url=http://localhost/servlet/MailServlet
datf=`mktemp ${datdir}/tmp.inmail.XXXXXX` || exit 1
 
cat <&> ${datf} || exit 1
 
w3m -dump -no-mouse -no-cookie -post ${datf} ${url} > /dev/null 2>&1
rm -f ${datf}

MailServlet を作成します。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
import java.io.IOException;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.mail.Session;
import javax.mail.MessagingException;
import javax.mail.internet.MimeMessage;
 
public class MailServlet extends HttpServlet{
 
    public void doPost(
                    HttpServletRequest request,
                    HttpServletResponse response)
                        throws IOException, ServletException{
        try{
            Session sess = Session.getDefaultInstance(
                            new java.util.Properties(),
                            null);
            MimeMessage mm = new MimeMessage(sess, request.getInputStream());
            // mm を使った処理
        }
        catch(MessagingException me){
            throw new ServletException(me);
        }
    }
}

上記によってアカウントinmail宛てのメール内容がMailServletにPOSTされます。MailServletでは InputStreamからMimeMessageを構築することができ、JavaMail APIを使って簡単にメールの処理が行えるようになります。これによって、メールの添付ファイルを処理する場合などもコードが単純化されます。また、この方法では受信メールをポーリングする方法に比べると不要な負荷が発生せず、処理のタイムラグも少なくなります。

この例では w3m を利用しましたが、メールの内容をhttp POSTすることが目的ですので、その部分をC言語やperl、PHPなどを用いて実装することも可能です。

実運用ではServletでローカルホスト以外からのリクエストを拒否したり、最大サイズのチェック、エラー処理などを行う必要があります。



NOTE: .forwardの終了コード75(EX_TEMPFAIL)は、エラー発生時にバウンスさせずに後で再試行させるためのコードです。