RequestHandler


RequestHandlerとは、Webブラウザからのリクエストを受付、応答を返す役割を持っています。

Hello World!

Google App Engine Launcherの、File > Create New Application… から新しいアプリケーションを作成すると、Hello worldを表示するRequestHandlerが生成されます。

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
28
29
30
31
32
33
#!/usr/bin/env python
#
# Copyright 2007 Google Inc.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
#     http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
from google.appengine.ext import webapp
from google.appengine.ext.webapp import util


class MainHandler(webapp.RequestHandler):
    def get(self):
        self.response.out.write('Hello world!')


def main():
    application = webapp.WSGIApplication([('/', MainHandler)],
                                         debug=True)
    util.run_wsgi_app(application)


if __name__ == '__main__':
    main()

17行目、18行目

webappモジュールとutilモジュールをインポートしています。

21行目

webapp.RequestHandlerクラスを継承したMainHandlerクラスを定義しています。

22行目~23行目

getメソッドをオーバーライド(上書き)しています。get(URLに対する通常のアクセス)を受け取ったときに、このメソッドが実行されます。self.response.out.write()の中身がWebブラウザに返されます。

26行目~29行目

重要な部分は、[('/', MainHandler)]です。”/”へのアクセスをMainHandlerに渡すように設定されています。”/page”へのアクセスをPageHandlerに渡したければ、[('/', MainHandler),('/page', PageHandler)]という風に書き換えます。

32行目~33行目

このpyファイルが直接呼び出されたときにmain関数を実行します。書き換えることはないので、おまじないだと思っていても問題ありません。

複数のRequestHandler

リクエストハンドラーを複数用いた例です。

  • MainHandler
    ルートディレクトリに対するリクエストを処理します。
  • Page1Handler
    /page1 に対するリクエストを処理します。
  • Page2Hander
    /page2 に対するリクエストを処理します。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
#!/usr/bin/env python
from google.appengine.ext import webapp
from google.appengine.ext.webapp import util

class MainHandler(webapp.RequestHandler):
    def get(self):
        self.response.out.write('MainPage <a href="/page1">Page1</a> <a href="/page1">Page2</a>')

class Page1Handler(webapp.RequestHandler):
    def get(self):
        self.response.out.write('Page1 [ <a href="/">Back to MainPage</a> ]')

class Page2Handler(webapp.RequestHandler):
    def get(self):
        self.response.out.write('Page2 [ <a href="/">Back to MainPage</a> ]')

def main():
    application = webapp.WSGIApplication(
    [('/', MainHandler),('/page1', Page1Handler),('/page1', Page2Handler)], debug=True)
    util.run_wsgi_app(application)

if __name__ == '__main__':
    main()

リクエストハンドラー(URL内変数埋込)

上記の2つのソースコードでは、URLは固定(定数)になっていましたが、記事番号などの変数を含めたい場合もあります。そういう場合は、リクエストハンドラーのURLに正規表現を使います。

  • 11行目
    ‘/(.*)’を満たす場合にMainHandlerに処理を委譲します。/の後ろに0文字以上の文字が続くという条件になっています。 例) /, /123, /hoge, /bakabakabaka
  • 6行目
    getの引数が2つになりました。2番目の引数に、’/(.*)’の括弧の中の値が渡されます。
  • 12行目
    渡された引数をそのまま表示しています。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
#!/usr/bin/env python
from google.appengine.ext import webapp
from google.appengine.ext.webapp import util

class MainHandler(webapp.RequestHandler):
    def get(self, value):
        self.response.out.write("value = %s" % value)

def main():
    application = webapp.WSGIApplication(
    [('/(.*)', MainHandler)], debug=True)
    util.run_wsgi_app(application)

if __name__ == '__main__':
    main()

実行例

この方法で変数を渡すと、静的ページのように見えるので、SEOに良いはずです。(とはいえ、最近の検索エンジンは賢いので、わざわざ静的ページに見えるようにしなくても大丈夫かもしれません。)

GETやPOSTの受け取り

GETとPOSTでの値の受け取り例を紹介する。

  • 7行目
    GETでvalueに渡された値を取り出す。GETで渡された変数も、POSTで渡された変数も同じ関数で取り出せます。
  • 8行目
    GETで渡された変数を画面に表示。
  • 9行目~13行目
    入力フォームを表示します。MethodはPOSTで、送信先は”/”を指定しています。
  • 14行目~16行目
    POSTを受け付けた場合はpostメソッドが呼び出されます。POSTで渡された値もGETで渡された値と同じ方法で取得できます。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
#!/usr/bin/env python
from google.appengine.ext import webapp
from google.appengine.ext.webapp import util

class MainHandler(webapp.RequestHandler):
    def get(self):
        value = self.request.get('value')
        self.response.out.write(value)
        self.response.out.write("""
        <form method="post" action="/">
            <input type="text" name="postvalue"/>
            <input type="submit" value="submit"/>
        </form>"""
)
    def post(self):
        postvalue = self.request.get('postvalue')
        self.response.out.write(postvalue)

def main():
    application = webapp.WSGIApplication(
    [('/', MainHandler)], debug=True)
    util.run_wsgi_app(application)

if __name__ == '__main__':
    main()

実行例

/?value=python にアクセスすると、GETでvalueに文字列”python”が渡され、ブラウザにpythonと表示される。

テキストフィールドに文字を入力して、ボタンをクリックすると・・・

入力した値が画面に表示されます


Leave a Reply