動くソレ

諸々なんとかなったので中身は微妙ですが備忘って事で記録しておきます。

main 手続き

以下。

def main():
    application = webapp.WSGIApplication([("/", MainHandler),
                                          ("/list", ListHandler),
                                          ("/fetch/(\w+)", FetchHandler),
                                          ("/add", AddHandler),
                                          ("/update/(\w+)", UpdateHandler),
                                          ("/delete/(\w+)", DeleteHandler),
                                          ],
                                         debug=True)
    util.run_wsgi_app(application)


if __name__ == "__main__":
    main()
  • /list な URI は ListHandler クラスが処理
    • 全件抽出
  • /fetch/id な URI は FetchHandler クラスが処理
    • 一件抽出
  • /add な URIAddHandler クラスが処理
  • /update/id な URI は UpdateHandler クラスが処理
  • /delete/id な URI は DeleteHandler クラスが処理

とゆー事で以下で一つづつ。

ListHandler クラス

の前にモデルを。notepad って事でメモのタイトルとその中身。

class Notepad(db.Model):
    title = db.StringProperty()
    body = db.StringProperty(multiline=True)

実はデバグ用に get なメソドも用意してるんですが同じ事してるだけなので略します。基本的には上記の通り全件抽出してそれらを JSON なオブジェクトに変換して戻しているのみ。

class ListHandler(webapp.RequestHandler):
    def post(self):
        list = Notepad.all()
        array = []
        for item in list:
            titleList = dict()
            titleList["title"] = item.title
            titleList["id"] = item.key().id()
            array.append(titleList)

        data = dict()
        data["List"] = array

        self.response.content_type = "application/json"
        self.response.out.write(simplejson.dumps(data, ensure_ascii=False))

全件読み出して id とタイトルなリストにして List というタグを尽けて json にしてレスポンスとして戻しています。ちなみに Android 側の i/f が以下なカンジ。

    public JSONArray fetchAllNotes() throws Exception {
        return makeRequest(mCtx, "/list").getJSONArray("List");
    }

レスポンスに対して List なタグで JSONArray を戻してます。昨晩のログにもある通り、db.key().id() というソレを発見するのに若干苦労していたり。

FetchHandler クラス

こちらは一件読み出す用。

class FetchHandler(webapp.RequestHandler):
    def post(self, key):
        notepad = Notepad.get_by_id(long(key))
        item = dict()
        array = []
        item["title"] = notepad.title
        item["body"] = notepad.body

        array.append(item)
        data = dict()
        data["item"] = array

        self.response.content_type = "application/json"
        self.response.out.write(simplejson.dumps(data, ensure_ascii=False))

こちらは id で get する get_by_id というメソドを見つけるまでハマりました。ちなみにこちらの Android 側の i/f は以下な記述となってます。

    public JSONArray fetchNote(long rowId) throws Exception {
    	JSONArray ret = makeRequest(mCtx, "/fetch/" + rowId).getJSONArray("item");

戻されたレスポンスな JSON オブジェクトから item というタグで JSONArray 取り出して戻してます。なんで JSONArray にする事にしたのかは忘れました。もう少し工夫ができそうな気がしてます。

AddHandler クラス

一件追加用。ここでは List な JSONArray が戻されていて困ったんですが

  • 例外発生してたら List が戻る
  • simplejson.dumps なフィルタかけずに self.response.out.write してた

という事が分からず printf デバグの世話になりますたorz
クラス定義は以下です。

class AddHandler(webapp.RequestHandler):
    def post(self):
        try:
            notepad = Notepad()
            title = cgi.escape(self.request.get("title"))
            body = cgi.escape(self.request.get("body"))
            notepad.title = title
            notepad.body = body
            notepad.put()
            key = notepad.key().id()
            data = dict()
            data["id"] = key

            self.response.content_type = "application/json"
            self.response.out.write(simplejson.dumps(data, ensure_ascii=False))
        except:
            self.redirect("/list")

ええと、id 戻さないといけないのでレスポンスで戻してます。あと例外発生時に /list にリダイレクトしているのは適切ではない事は承知してますが手を抜いてます。
Android 側の i/f は以下ですな。

    public long createNote(String title, String body) throws Exception {
    	JSONObject tmp = makeRequest(mCtx, title, body);
    	
    	return tmp.getLong("id");
    }

id を戻してます。ちなみに makeRequest の中では title とか body とかを HTTP なパラメータとしてサーバ側に渡しているので、

            title = cgi.escape(self.request.get("title"))
            body = cgi.escape(self.request.get("body"))

みたいな形で取得しています。セットしてる側の記述的には以下か。

        List<NameValuePair> params = new ArrayList<NameValuePair>();
        params.add(new BasicNameValuePair("title", title));
        params.add(new BasicNameValuePair("body", body));

        HttpResponse r = client.makeRequest("/add", params);

UpdateHandler クラス

更新と削除についてはレスポンスを戻していませんので記述が簡潔です。

class UpdateHandler(webapp.RequestHandler):
    def post(self, key):
        try:
            notepad = Notepad.get_by_id(long(key))
            title = cgi.escape(self.request.get("title"))
            body = cgi.escape(self.request.get("body"))
            notepad.title = title
            notepad.body = body
            notepad.put()
        except:
            self.redirect("/list")

こちらもパラメータから取り出して put してるのみ。更新とか削除については id を渡してあげなきゃいけないのですが、基本的には URI に仕込まれています。Android 側の i/f が以下。

    public boolean updateNote(long rowId, String title, String body) throws Exception {
    	makeRequest(mCtx, "/update/" + rowId, title, body);

    	return true;
    }

DeleteHandler クラス

削除な記述は以下です。

class DeleteHandler(webapp.RequestHandler):
    def post(self, key):
        try:
            notepad = Notepad.get_by_id(long(key))
            if notepad:
                notepad.delete()
        except:
            self.redirect("/list")

しかし例外発生時の適切な処理ってどうやるんかな。

  catch (Exception e) {
      e.printStacktrace();
  }

みたいな便利なナニがあるはずなんだけど。

とりあえず

Android 側は別途出力します。