實際上handler有很多講究,在Application類的註釋中,就講了不少。
1. 首先,(regexp,tornado.web.RequestHandler)中的第一個參數不是普通的字符串,而是正則表達式,這也是爲什麼示例中它帶了一個前綴“r”。這說明一個handler可以匹配很多個request。只要它們的request url能滿足regexp匹配。
如果我們把剛纔的
1 |
application = tornado.web.Application([(r "/hello\.htm" ,
MainHandler), ]) |
改成
1 |
application = tornado.web.Application([(r "/hello.htm" ,
MainHandler), ]) |
只去掉了一個反斜槓,意義就大變。正則表達式中,句點“.”表示任意一個字符。
那麼下面的URL將都會輸出”Hello World”:
1 |
http: / / 127.0 . 0.1 : 8888 / hello.htm |
2 |
http: / / 127.0 . 0.1 : 8888 / hello_htm |
3 |
http: / / 127.0 . 0.1 : 8888 / hello1htm |
以下的URL因爲不符合[r"/hello.htm"]的規則,會輸出404 Not Found。
1 |
http: / / 127.0 . 0.1 : 8888 / hello.html |
2 |
http: / / 127.0 . 0.1 : 8888 / hello11htm |
另外,這樣的URL也會返回404 Not Found,你知道爲什麼嗎?
1 |
http: / / 127.0 . 0.1 : 8888 / hello?htm |
2. 可以定義多個handler tuple,形成一個列表(你可能已經注意到了,示例中application的參數是一個tuple列表)。用戶請求到來時,會依次按列表中的handler進行匹配,第一個找到的匹配(不是最精確的那個匹配)會被調用。
3. 每個tuple都可以有第三個可選元素。這個元素是一個dictionary對象,它將作爲參數傳遞給tuple中的Handler函數。比如:
1 |
application = web.Application([ |
2 |
(r "/static/(.*)" ,
web.StaticFileHandler, { "path" : "/var/www" }), |
4. 除了在Application的構造函數中直接定義Handler外,application對象也可以調用其add_handlers()方法來完成。這個函數還有一個額外的功能,即支持Virtual
Host功能。
1 |
application.add_handlers(r "www\.nowamagic\.net" ,
[(r "/article/([0-9]+)" ,
ArticleHandler), ]) |
如上,www.nowamagic.net就是一個Virtual Host。什麼是Virtual Host呢?
常規情況下,一個IP對應一個域名、一個網站,Virtual Host就是讓一個IP上可以存在多個域名,每個域名對應不同的網站。
這個功能的實現其實很簡單,網上有很多介紹,不羅嗦了。
5. 靜態文件怎麼辦呢?比如圖片文件,服務器唯一要做的就是把圖片直接返回給客戶,這就是web server默認的行爲。我們根本不需要handler來處理(不是說不行,而是嫌它多此一舉)。Application的handler也爲靜態文件提供了方便。
Tornado默認把網站根目錄下的“/static/”子目錄都作爲靜態路徑看待,訪問這下面的文件不需要經過handler動態處理,webserver自動會將文件返回給客戶。它適合放一些不需要動態處理的圖片,css樣式表,音樂等等。
當然,這個路徑是可以自己調整的,就在Application.__init__函數的settings參數中指定。
1 |
def __init__( self ,
handlers = None ,
default_host = "",
transforms = None ,
wsgi = False , * * settings): |
6. 你也看到了,settings參數是一個dictionary。這裏面是一些雜項設置。下面是一個例子。
02 |
blog_title = u "nowamagic" , |
03 |
template_path = os.path.join(os.path.dirname(__file__), "templates" ), |
04 |
static_path = os.path.join(os.path.dirname(__file__), "static" ), |
05 |
ui_modules = { "Entry1" :
EntryModule, "topx" :
TopXModule}, |
07 |
cookie_secret = "__TODO:_GENERATE_YOUR_OWN_RANDOM_VALUE_HERE__" , |
settings 裏面提供的,既有tornado的內置選項(比如static_path,cokeei_secret, debug等),也有用戶自定義選項(如blog_title)。內置選項會由Application類自己處理,自定義選項則需要用戶自己寫程序處理。
這些選項的用途,我們後面會逐漸講到。