• Tornado RequestHandler和Application类

    了解web.py文件
    服务器君一共花费 16.087 ms 进行了 2 次数据库查询,努力地为您提供了这个页面。
    广告很萌的

    前面一小节提到了需要了解 web.py 这个文件,这个文件最关键的地方是定义了 Application 和 RequestHandler 类。我们再看看 Tornado 的 Hello World,我们再精简一下,下面是最简单的实例化并启动 Application 的方式:

    import ioloop
    import web
    
    application = web.Application([
        (r'/', MainHandler),
    ])
    application.listen(8888)
    ioloop.IOLoop.instance().start()
    

    从代码里可以看到的是:应用里定义了 URI 路由和对应的处理类,并以此构建了application对象,然后让这个对象监听在8888端口,最后由 ioloop 单例进入循环,不断分发事件。

    这里的URI路由就是r"/",对应处理类就是 MainHandler,它们被放在同一个 tuple 里形成了关联。可以看到,application 是接受一个列表的,因此可以定义多个全局路由对应不同处理,往列表里 append 就是了。

    如果只是在 tornado 的框架基础上进行开发,那就只需要不断定义不同的处理类,并把对应路由与其关联即可。

    tornado.web 里的 RequestHandler 和 Application 类

    Tornado 使用 web 模块的 Application 做URI转发,然后通过 RequestHandler 处理请求。 Application 提供了一个 listen 方法作为 HTTPServer 中的 listen 的封装。

    初始化 Application 时,一般将处理器直接传入,它会调用 add_handlers 添加这些处理器,初始化还包括 transforms (分块、压缩等)、UI模块、静态文件处理器的初始化。 add_handlers 方法负责添加URI和处理器的映射。

    Application 实现 URI 转发时使用了一个技巧,它实现了 __call__ 方法,并将 Application 的实例传递给 HTTPServer ,当监听到请求时,它通过调用 Application 实例触发 __call__ 。 __call__ 方法中完成具体的URI转发工作,并调用已注册的处理器的 _execute 方法,处理请求。

    def __call__(self, request):
        transforms = [t(request) for t in self.transforms]
        handler = None
        args = []
        kwargs = {}
        handlers = self._get_host_handlers(request) # 取得请求的host的一组处理器
        if not handlers:
            handler = RedirectHandler(
                self, request, url="http://" + self.default_host + "/")
        else:
            for spec in handlers:
                match = spec.regex.match(request.path)  # 匹配请求的URI
                if match:
                    handler = spec.handler_class(self, request, **spec.kwargs) # 实例化
                    if spec.regex.groups:   # 取得参数
                        ...
                        if spec.regex.groupindex:
                            kwargs = dict(
                                (str(k), unquote(v))
                                for (k, v) in match.groupdict().iteritems())
                        else:
                            args = [unquote(s) for s in match.groups()]
                    break
            if not handler:     # 无匹配
                handler = ErrorHandler(self, request, status_code=404)
        ...
        handler._execute(transforms, *args, **kwargs)   # 处理请求
        return handler
    

    RequestHandler 完成具体的请求,开发者需要继承它,并根据需要,覆盖 head 、 get 、 post 、 delete 、 patch 、 put 、 options 等方法,定义处理对应请求的业务逻辑。

    RequestHandler 提供了很多钩子,包括 initialize 、 prepare 、 on_finish 、 on_connection_close 、 set_default_headers 等等。

    下面是 _execute 的处理流程:

    RequestHandler 中涉及到很多 HTTP 相关的技术,包括 Header、Status、Cookie、Etag、Content-Type、链接参数、重定向、长连接等等,还有和用户身份相关的XSRF和CSRF等等。这方面的知识可以参考《HTTP权威指南》。

    Tornado默认实现了几个常用的处理器:

    • ErrorHandler :生成指定状态码的错误响应。
    • RedirectHandler :重定向请求。
    • StaticFileHandler :处理静态文件请求。
    • FallbackHandler :使可以在Tornado中混合使用其他HTTP服务器。

    上面提到了 transform ,Tornado 使用这种机制来对输出做分块和压缩的转换,默认给出了 GZipContentEncoding 和 ChunkedTransferEncoding 。也可以实现自定义的转换,只要实现 transform_first_chunk 和 transform_chunk 接口即可,它们由 RequestHandler 中的 flush 调用。

更多 推荐条目

Welcome to NowaMagic Academy!

现代魔法 推荐于 2013-02-27 10:23   

本章最新发布
随机专题
  1. [软件工程与项目管理] 浏览器与CSS渲染技巧 2 个条目
  2. [移动开发] 从代码角度去认识HttpClient 2 个条目
  3. [C语言程序设计] C语言里的全局变量 2 个条目
  4. [运维管理] 路由器与交换机 4 个条目
  5. [移动开发] Android与SQLite数据库 7 个条目
  6. [计算机算法] TAOCP与算法 12 个条目
  7. [PHP程序设计] htaccess 设置技巧 6 个条目
  8. [PHP程序设计] PHP数组探索 4 个条目
  9. [Python程序设计] Django Web环境配置 2 个条目
  10. [Python程序设计] Django与表单 4 个条目
  11. [JavaScript程序设计] 关于HTTP Keep-Alive 6 个条目
  12. [移动开发] Activity 初步知识 2 个条目
窗口 -- [八点]