Hatena::ブログ(Diary)

winplusの日記 このページをアンテナに追加 RSSフィード

2011-01-16

Weight Note:スーパーシンプルなダイエット支援サービス、とGAEへの小言

スーパーシンプルなダイエット支援サービス『textWeight』 | 100SHIKIをお題にして、いつものJAX-RS on GAE/Jで作ってみました。といっても紹介されているサイト(textWeight)は見ていません。そもそも日本の携帯電話では無理でしょうし。お題の記事を参考に、とりあえず以下のような機能だけを実装しました。

  1. 毎朝8:00頃にメールが届きます。
  2. 件名に体重をいれて、返信します。
  3. 体重の変化は、いつでも確認できます(URLはメールに記述されています)。

これだけの簡単なものです。ポイントになるのは、メールの扱い方だけ。GAE(Google App Engine)はメールを受信すると、それをHTTPリクエストに変換してくれます。

appengine-web.xml

<inbound-services>
    <service>mail</service>
</inbound-services>

web.xml

<security-constraint>
    <web-resource-collection>
        <url-pattern>/_ah/mail/*</url-pattern>
    </web-resource-collection>
    <auth-constraint>
        <role-name>admin</role-name>
    </auth-constraint>
</security-constraint>

これだけの設定で、適当な文字列@アプリ名.appspotmail.com宛に送信されたメールが、/_ah/mail/文字列@アプリ名.appspotmail.comへのPOSTリクエストになります。なので、JAX-RSでも簡単に扱うことができます。

@Path("/_ah/mail/{toAddress}")
public class MailReceiver {
	
    @POST
    public Response createRecord(@PathParam("toAddress") String toAddress, InputStream stream){
    	Session session = Session.getDefaultInstance(System.getProperties(), null);
    	MimeMessage message = new MimeMessage(session, stream);
	fromAddress = ((InternetAddress)message.getFrom()[0]).getAddress();

こんな感じで、送信・受信のメールアドレスも簡単にとりだせるのです。RESTふうともいえる、じつに上手い扱い方だと思います。

で、小言。

メールの処理に失敗したときは、このメソッドでエラーのレスポンスコードを返します。そうすれば、適当な間隔で自動的にリトライしてくれます。これも便利なのです。ところが「成功した」という判断を、どうやらステータスコード200(OK)が返されたかどうかで判断しているようなのです。

メール受信を変換したリクエストなので、処理に成功しても何かの内容を返信することはできません。なので、以下のようにこのメソッドを終了させていました。

return Response.ok().build();

このとき、内容が空なので、JAX-RSステータスコード204(No Content)を返します。すると、GAEは、これをエラーとみなしてリトライを行うのです。この仕様のせいで、どれだけ悩んだことか。ちなみにTaskQueなんかも同じで、処理が成功したときは、やはりステータスコード200(OK)を返す必要があります。

ステータスコード2xxはすべて処理が成功したことを示すのですから、ステータスコード200(OK)と同じように扱うべきじゃないの、というのが小言です。せっかくHTTPリクエストとして扱えるという素晴らしいアイデアを実現しているのに、ツメが甘いのでは...。

Weight Note:スーパーシンプルなダイエット支援サービス

  • 01/16 試作品を公開開始