• 理解Tornado里的handler

    URL控制的概念
    服务器君一共花费 9.220 ms 进行了 3 次数据库查询,努力地为您提供了这个页面。
    广告很萌的

    前面我们对 Tornado 自带的 hello world 作了代码组织上的解释,但是没有更加深入细致地解释。这里我们直接从main()函数开始,单步跟随,看看tornado都干了些什么。

    下面是 main() 函数的定义:

    def main():
        tornado.options.parse_command_line()
        application = tornado.web.Application([
            (r"/", MainHandler),
        ])
        http_server = tornado.httpserver.HTTPServer(application)
        http_server.listen(options.port)
        tornado.ioloop.IOLoop.instance().start()
    

    先从第一行开始:

    tornado.options.parse_command_line()
    

    这一句是解析命令行参数,函数定义在tornado/options.py里。注意,在options.py里有两个parse_command_line()的定义。一个是OptionParser类的成员函数:

    class OptionParser(object): 
        def parse_command_line(self, args=None, final=True):
    

    另一个是普通的函数,不过它的实现是直接调用OptionParser的实现。

    def parse_command_line(args=None, final=True): 
        return options.parse_command_line(args, final=final) 
    

    直接看OptionParser中的实现。简短的注释,parse_command_line()默认是解析sys.argv中的参数。我们在运行helloworld.py时,后面跟的参数在这里处理。命令行参数的解析过程很简单,没有什么需要特别关注。再者,我们现在没有使用任何命令行参数,所以先略过。

    接下来:

    application = tornado.web.Application([ 
    	(r"/", MainHandler), ]) 
    

    这一句虽然简单,但信息量略大。首先,tornado.web.Application是一个tornado内置的类,定义在tornado/web.py中。从它大段的注释就可以看出来,这个类至少是男二号。按tornado的说法,Application类实际是一些Handler的集合,这些Handler组成了一个web应用程序。

    什么是handler呢?

    当用户访问你的网站时,它会提交一个URL,表示“把这个地址的数据给我”,这个URL可能是一张网页,比如http://abc.com/1.htm,也可能是一张图片,比如 http://abc.com/2.jpg 。数据被传送到浏览器后,经过渲染,就是大家看到的网站的样子。对每个这样的URL,在tornado上可以针对性的设置一个函数来处理。 比如http://abc.com/1.htm我们就交给一个叫handle_1_htm()的函数,http://abc.com/2.jpg交给一个叫handle_2_jpg()的函数。它们分别负责将客户请求的内容通过http协议返回给客户端。这些函数,就叫handler。

    相比于普通的静态http,这种handler机制提供了更多的灵活性。比如,1.htm可能每次都是根据数据库中内容动态生成的,再返回给用户的资料可以每次都不一样。又比如:可能服务器上根本不存在2.jpg这样一个文件,handle_2_jpg()函数实际上从服务器连接的摄像头上去拍一张图来,然后返回给用户。用tornado开发网站,大部分的工作都是在写这样的 handler

    上面这一句,是初始化了一个Application的实例,保存在application变量中。

    Application的初始化参数是非常讲究的。在Application类的说明里,大段的话都是在讲参数的事。

    示例中的参数比较简单:

    application = tornado.web.Application([(r"/", MainHandler), ])
    

    我们看Applicatino类的__init__函数原型:

    def __init__(self, handlers=None, default_host="", transforms=None, wsgi=False, **settings): 
    

    可见helloword.py只提供了handlers这个参数值。handlers实际上是一个列表,每个元素是(regexp,tornado.web.RequestHandler)这样的tuple。前面讲过,handler与用户请求之间存在映射关系,这个关联就是在这里定义的。

    (r"/", MainHandler)
    

    这就表示,如果用户请求的是网站根目录,就调用MainHandler来处理。前面我们直接输入 http://127.0.0.1:8888 ,其实就是访问的根目录,我们看到的hello world输出就是由MainHandler输出的。后面分析MainHandler时再详述。

    如果我们访问一个没有定义handler的URL(比如http://127.0.0.1/1.htm )会发生什么?

    很简单,告诉你找不到!再做个实验,把

    application = tornado.web.Application([(r"/", MainHandler),])
    

    改成:

    application = tornado.web.Application([ (r"/hello\.htm", MainHandler), ]) 
    

    注意,因为是正则式,所以我们在点号前加了反斜杠。再尝试访问http://127.0.0.1:8888,会404了。

    换我们改过的URL,http://127.0.0.1:8888/hello.htm,可爱的“hello world”又回来了。

    现在你应该理解handler是怎么回事了。

    同时这提醒我们,浏览器地址栏中的URL并不一定表示服务器上真的就存在这样一个文件。它完全可能是web服务器上虚拟映射的一个路径而已。比如刚才的hello.htm。

    由于这是hello world级别的示例,所以handler只有一个,且非常之简单。

更多 推荐条目

Welcome to NowaMagic Academy!

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

本章最新发布
随机专题
  1. [软件工程与项目管理] 浏览器初步介绍 8 个条目
  2. [Python程序设计] 标准库:urllib/urllib2 14 个条目
  3. [PHP程序设计] PHP数组探索 4 个条目
  4. [计算机算法] 两数交换的各种算法细节 2 个条目
  5. [Python程序设计] Python数据类型 11 个条目
  6. [运维管理] 防火墙原理与应用 5 个条目
  7. [PHP程序设计] PHP与函数式编程 1 个条目
  8. [移动开发] 简单了解Android Fragment 3 个条目
  9. [Python程序设计] Django后台管理系统 2 个条目
  10. [移动开发] Android View注入框架Butter Knife 3 个条目
  11. [PHP程序设计] PHP与Stream流 5 个条目
  12. [数据库技术] SQL基础语法 1 个条目
窗口 -- [协会]