RequestHandler
首先我们得知道C/S(客户端/服务器)的工作原理,即服务器被动地捕获(监听)客户端的信息,并对客户端发送来的请求选择性地完成某项行为并反馈给客户。我们通常使用的网页基本就是基于这一原理的。比如你在网页上点击一按钮,那么就会有一条“某某按钮被按下”的请求发送给当前网页的后台服务器。服务器收到这条请求后,可能返回一条“刷新”的指令到你的浏览器,那么你的浏览器作为客户端收到这条指令便执行刷新行为,于是一个C/S过程就完成了。
RequestHandler顾名思义就是服务器处理客户端请求的一个类,它的主要任务就是上述接受“某某按钮被按下”的请求,并返回“刷新”指令。
RequestHandler是个好东西= =*,大多数Tornado网页应用的具体行为都是在继承了RequestHandler的子类里完成的。handler子类可以利用get(),post()等方法处理接受到的各种各样的网页请求(request),而每一个handler可以定义多个get(),post()等方法。通常这些方法都有一个参数self,代表自身的RequestHandler对象。在handler内,利用self调用self.render(...)(RequestHandler.render(...))或者self.write(...)(RequestHandler.write(...))等函数执行一些行为。render通过名字加载一个模板(template),可以是html等文件。write是基于非模板类的输出,它接受字符串(strings)、字节(bytes)和字典(dictionaries)作为输出。
那么RequestHandler是怎么工作的呢?
哈哈,其实每当RequestHandler收到一个request请求,都将依次执行下面的步骤:
1.新的RequestHandler对象被创建(对应每一个请求)
2.对象的initialize()被调用,传入的参数来自Application组态。initialize应该只把传入的参数保存在自身的成员变量中,而不应该提供任何的输出或调用如send_error等方法。
3.对象的prepare()被调用,这是你所有handler子类所继承的最有用的函数,因为不管哪一个HTTP方法被使用prepare都会被调用,并且prepare可以提供输出。如果prepare里使用了finish或者redirect(etc),那么进程就在此结束。
4.其中一个HTTP方法(get()/post()/put() .etc)被调用,如果URL的正则表达式含有捕获信息,那么额外的参数将被传入这个方法。如[url(r"/reverse/(\w+)",ReverseHandler)],那么在class ReverseHandler(tornado.web.RequestHandler)类里就可以使用def get(self, input):,其中传入的参数input就是url正则表达式中(\w+)捕获信息提供的。
import tornado.httpserver
import tornado.ioloop
import tornado.options
import tornado.web
class ReverseHandler(tornado.web.RequestHandler):
def get(self, input):
self.write(input[::-1])
if __name__ == "__main__":
tornado.options.parse_command_line()
app = tornado.web.Application(
handlers=[
(r"/reverse/(\w+)", ReverseHandler),
]
)
http_server = tornado.httpserver.HTTPServer(app)
http_server.listen(8000)
tornado.ioloop.IOLoop.instance().start()
5.当请求任务完成时,对象的on_finish()函数被调用。值得注意一点的是,on_finish函数在单线程handler里是紧跟get()(etc)返回后执行的,而在异步handler里它是在finish()后执行的。
除了get()/post()/..等方法,RequestHandler还有许多方法需要程序员重写才能利用。因此常见的方法是自己先定义一个BaseHandler继承RequestHandler,然后重写里面的一些函数,使用时再继承BaseHandler,而不是到使用时再在每个类里重写RequestHandler。
所有的重写方法可以在官方文档里查到:http://www.tornadoweb.org/en/stable/web.html#tornado.web.RequestHandler
一些最常被重写的方法包括:
write_error - 渲染错误页面的HTML
on_connection_close - 当客户掉线时被调用
get_current_user - 查看客户认证
get_user_locale - 返回可被当前客户使用的Locale对象
set_default_headers - 可以用来添加更多的headers