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と表示される。
テキストフィールドに文字を入力して、ボタンをクリックすると・・・
