(2018-05-26.Python從Zero到One)8、(Tornado)深入tornado__1.3.3輸出

3.3 輸出

1. write(chunk)

將chunk數(shù)據(jù)寫到輸出緩沖區(qū)。如我們?cè)谥暗氖纠a中寫的:

class IndexHandler(RequestHandler):
    def get(self):
        self.write("hello itcast!")

想一想,可不可以在同一個(gè)處理方法中多次使用write方法?

下面的代碼會(huì)出現(xiàn)什么效果?

class IndexHandler(RequestHandler):
    def get(self):
        self.write("hello itcast 1!")
        self.write("hello itcast 2!")
        self.write("hello itcast 3!")

write方法是寫到緩沖區(qū)的,我們可以像寫文件一樣多次使用write方法不斷追加響應(yīng)內(nèi)容,最終所有寫到緩沖區(qū)的內(nèi)容一起作為本次請(qǐng)求的響應(yīng)輸出。

想一想,如何利用write方法寫json數(shù)據(jù)?

import json

class IndexHandler(RequestHandler):
    def get(self):
        stu = {
            "name":"zhangsan",
            "age":24,
            "gender":1,
        }
        stu_json = json.dumps(stu)
        self.write(stu_json)

實(shí)際上,我們可以不用自己手動(dòng)去做json序列化,當(dāng)write方法檢測(cè)到我們傳入的chunk參數(shù)是字典類型后,會(huì)自動(dòng)幫我們轉(zhuǎn)換為json字符串。

class IndexHandler(RequestHandler):
    def get(self):
        stu = {
            "name":"zhangsan",
            "age":24,
            "gender":1,
        }
        self.write(stu)

兩種方式有什么差異?

對(duì)比一下兩種方式的響應(yīng)頭header中Content-Type字段,自己手動(dòng)序列化時(shí)為Content-Type:text/html; charset=UTF-8,而采用write方法時(shí)為Content-Type:application/json; charset=UTF-8。

write方法除了幫我們將字典轉(zhuǎn)換為json字符串之外,還幫我們將Content-Type設(shè)置為application/json; charset=UTF-8

2. set_header(name, value)

利用set_header(name, value)方法,可以手動(dòng)設(shè)置一個(gè)名為name、值為value的響應(yīng)頭header字段。

用set_header方法來完成上面write所做的工作。

import json

class IndexHandler(RequestHandler):
    def get(self):
        stu = {
            "name":"zhangsan",
            "age":24,
            "gender":1,
        }
        stu_json = json.dumps(stu)
        self.write(stu_json)
        self.set_header("Content-Type", "application/json; charset=UTF-8")

3. set_default_headers()

該方法會(huì)在進(jìn)入HTTP處理方法前先被調(diào)用,可以重寫此方法來預(yù)先設(shè)置默認(rèn)的headers。注意:在HTTP處理方法中使用set_header()方法會(huì)覆蓋掉在set_default_headers()方法中設(shè)置的同名header。

class IndexHandler(RequestHandler):
    def set_default_headers(self):
        print "執(zhí)行了set_default_headers()"
        # 設(shè)置get與post方式的默認(rèn)響應(yīng)體格式為json
        self.set_header("Content-Type", "application/json; charset=UTF-8")
        # 設(shè)置一個(gè)名為itcast、值為python的header
        self.set_header("itcast", "python")

    def get(self):
        print "執(zhí)行了get()"
        stu = {
            "name":"zhangsan",
            "age":24,
            "gender":1,
        }
        stu_json = json.dumps(stu)
        self.write(stu_json)
        self.set_header("itcast", "i love python") # 注意此處重寫了header中的itcast字段

    def post(self):
        print "執(zhí)行了post()"
        stu = {
            "name":"zhangsan",
            "age":24,
            "gender":1,
        }
        stu_json = json.dumps(stu)
        self.write(stu_json)

終端中打印出的執(zhí)行順序:

day60_tornado-深入tornado-01.png

get請(qǐng)求方式的響應(yīng)header:

day60_tornado-深入tornado-02.png

post請(qǐng)求方式的響應(yīng)header:

day60_tornado-深入tornado-03.png

4. set_status(status_code, reason=None)

為響應(yīng)設(shè)置狀態(tài)碼。

參數(shù)說明:

  • status_code int類型,狀態(tài)碼,若reason為None,則狀態(tài)碼必須為下表中的。
  • reason string類型,描述狀態(tài)碼的詞組,若為None,則會(huì)被自動(dòng)填充為下表中的內(nèi)容。
Code Enum Name Details
100 CONTINUE HTTP/1.1 RFC 7231, Section 6.2.1
101 SWITCHING_PROTOCOLS HTTP/1.1 RFC 7231, Section 6.2.2
102 PROCESSING WebDAV RFC 2518, Section 10.1
200 OK HTTP/1.1 RFC 7231, Section 6.3.1
201 CREATED HTTP/1.1 RFC 7231, Section 6.3.2
202 ACCEPTED HTTP/1.1 RFC 7231, Section 6.3.3
203 NON_AUTHORITATIVE_INFORMATION HTTP/1.1 RFC 7231, Section 6.3.4
204 NO_CONTENT HTTP/1.1 RFC 7231, Section 6.3.5
205 RESET_CONTENT HTTP/1.1 RFC 7231, Section 6.3.6
206 PARTIAL_CONTENT HTTP/1.1 RFC 7233, Section 4.1
207 MULTI_STATUS WebDAV RFC 4918, Section 11.1
208 ALREADY_REPORTED WebDAV Binding Extensions RFC 5842, Section 7.1 (Experimental)
226 IM_USED Delta Encoding in HTTP RFC 3229, Section 10.4.1
300 MULTIPLE_CHOICES HTTP/1.1 RFC 7231, Section 6.4.1
301 MOVED_PERMANENTLY HTTP/1.1 RFC 7231, Section 6.4.2
302 FOUND HTTP/1.1 RFC 7231, Section 6.4.3
303 SEE_OTHER HTTP/1.1 RFC 7231, Section 6.4.4
304 NOT_MODIFIED HTTP/1.1 RFC 7232, Section 4.1
305 USE_PROXY HTTP/1.1 RFC 7231, Section 6.4.5
307 TEMPORARY_REDIRECT HTTP/1.1 RFC 7231, Section 6.4.7
308 PERMANENT_REDIRECT Permanent Redirect RFC 7238, Section 3 (Experimental)
400 BAD_REQUEST HTTP/1.1 RFC 7231, Section 6.5.1
401 UNAUTHORIZED HTTP/1.1 Authentication RFC 7235, Section 3.1
402 PAYMENT_REQUIRED HTTP/1.1 RFC 7231, Section 6.5.2
403 FORBIDDEN HTTP/1.1 RFC 7231, Section 6.5.3
404 NOT_FOUND HTTP/1.1 RFC 7231, Section 6.5.4
405 METHOD_NOT_ALLOWED HTTP/1.1 RFC 7231, Section 6.5.5
406 NOT_ACCEPTABLE HTTP/1.1 RFC 7231, Section 6.5.6
407 PROXY_AUTHENTICATION_REQUIRED HTTP/1.1 Authentication RFC 7235, Section 3.2
408 REQUEST_TIMEOUT HTTP/1.1 RFC 7231, Section 6.5.7
409 CONFLICT HTTP/1.1 RFC 7231, Section 6.5.8
410 GONE HTTP/1.1 RFC 7231, Section 6.5.9
411 LENGTH_REQUIRED HTTP/1.1 RFC 7231, Section 6.5.10
412 PRECONDITION_FAILED HTTP/1.1 RFC 7232, Section 4.2
413 REQUEST_ENTITY_TOO_LARGE HTTP/1.1 RFC 7231, Section 6.5.11
414 REQUEST_URI_TOO_LONG HTTP/1.1 RFC 7231, Section 6.5.12
415 UNSUPPORTED_MEDIA_TYPE HTTP/1.1 RFC 7231, Section 6.5.13
416 REQUEST_RANGE_NOT_SATISFIABLE HTTP/1.1 Range Requests RFC 7233, Section 4.4
417 EXPECTATION_FAILED HTTP/1.1 RFC 7231, Section 6.5.14
422 UNPROCESSABLE_ENTITY WebDAV RFC 4918, Section 11.2
423 LOCKED WebDAV RFC 4918, Section 11.3
424 FAILED_DEPENDENCY WebDAV RFC 4918, Section 11.4
426 UPGRADE_REQUIRED HTTP/1.1 RFC 7231, Section 6.5.15
428 PRECONDITION_REQUIRED Additional HTTP Status Codes RFC 6585
429 TOO_MANY_REQUESTS Additional HTTP Status Codes RFC 6585
431 REQUEST_HEADER_FIELDS_TOO_LARGE Additional HTTP Status Codes RFC 6585
500 INTERNAL_SERVER_ERROR HTTP/1.1 RFC 7231, Section 6.6.1
501 NOT_IMPLEMENTED HTTP/1.1 RFC 7231, Section 6.6.2
502 BAD_GATEWAY HTTP/1.1 RFC 7231, Section 6.6.3
503 SERVICE_UNAVAILABLE HTTP/1.1 RFC 7231, Section 6.6.4
504 GATEWAY_TIMEOUT HTTP/1.1 RFC 7231, Section 6.6.5
505 HTTP_VERSION_NOT_SUPPORTED HTTP/1.1 RFC 7231, Section 6.6.6
506 VARIANT_ALSO_NEGOTIATES Transparent Content Negotiation in HTTP RFC 2295, Section 8.1 (Experimental)
507 INSUFFICIENT_STORAGE WebDAV RFC 4918, Section 11.5
508 LOOP_DETECTED WebDAV Binding Extensions RFC 5842, Section 7.2 (Experimental)
510 NOT_EXTENDED An HTTP Extension Framework RFC 2774, Section 7 (Experimental)
511 NETWORK_AUTHENTICATION_REQUIRED Additional HTTP Status Codes RFC 6585, Section 6
class Err404Handler(RequestHandler):
    """對(duì)應(yīng)/err/404"""
    def get(self):
        self.write("hello itcast")
        self.set_status(404) # 標(biāo)準(zhǔn)狀態(tài)碼,不用設(shè)置reason

class Err210Handler(RequestHandler):
    """對(duì)應(yīng)/err/210"""
    def get(self):
        self.write("hello itcast")
        self.set_status(210, "itcast error") # 非標(biāo)準(zhǔn)狀態(tài)碼,設(shè)置了reason

class Err211Handler(RequestHandler):
    """對(duì)應(yīng)/err/211"""
    def get(self):
        self.write("hello itcast")
        self.set_status(211) # 非標(biāo)準(zhǔn)狀態(tài)碼,未設(shè)置reason,錯(cuò)誤

day60_tornado-深入tornado-04.png
day60_tornado-深入tornado-05.png
day60_tornado-深入tornado-06.png

5. redirect(url)

告知瀏覽器跳轉(zhuǎn)到url。

class IndexHandler(RequestHandler):
    """對(duì)應(yīng)/"""
    def get(self):
        self.write("主頁")

class LoginHandler(RequestHandler):
    """對(duì)應(yīng)/login"""
    def get(self):
        self.write('<form method="post"><input type="submit" value="登陸"></form>')

    def post(self):
        self.redirect("/")

6. send_error(status_code=500, **kwargs)

拋出HTTP錯(cuò)誤狀態(tài)碼status_code,默認(rèn)為500,kwargs為可變命名參數(shù)。使用send_error拋出錯(cuò)誤后tornado會(huì)調(diào)用write_error()方法進(jìn)行處理,并返回給瀏覽器處理后的錯(cuò)誤頁面。

class IndexHandler(RequestHandler):
    def get(self):
        self.write("主頁")
        self.send_error(404, content="出現(xiàn)404錯(cuò)誤")

注意:默認(rèn)的write\_error()方法不會(huì)處理send\_error拋出的kwargs參數(shù),即上面的代碼中content="出現(xiàn)404錯(cuò)誤"是沒有意義的。

嘗試下面的代碼會(huì)出現(xiàn)什么問題?

class IndexHandler(RequestHandler):
    def get(self):
        self.write("主頁")
        self.send_error(404, content="出現(xiàn)404錯(cuò)誤")
        self.write("結(jié)束") # 我們?cè)趕end_error再次向輸出緩沖區(qū)寫內(nèi)容

day60_tornado-深入tornado-07.png

注意:使用send_error()方法后就不要再向輸出緩沖區(qū)寫內(nèi)容了!

7. write_error(status_code, **kwargs)

用來處理send_error拋出的錯(cuò)誤信息并返回給瀏覽器錯(cuò)誤信息頁面??梢灾貙懘朔椒▉矶ㄖ谱约旱腻e(cuò)誤顯示頁面。

class IndexHandler(RequestHandler):
    def get(self):
        err_code = self.get_argument("code", None) # 注意返回的是unicode字符串,下同
        err_title = self.get_argument("title", "")
        err_content = self.get_argument("content", "")
        if err_code:
            self.send_error(err_code, title=err_title, content=err_content)
        else:
            self.write("主頁")

    def write_error(self, status_code, **kwargs):
        self.write(u"<h1>出錯(cuò)了,程序員GG正在趕過來!</h1>")
        self.write(u"<p>錯(cuò)誤名:%s</p>" % kwargs["title"])
        self.write(u"<p>錯(cuò)誤詳情:%s</p>" % kwargs["content"])

day60_tornado-深入tornado-08.png
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • Spring Cloud為開發(fā)人員提供了快速構(gòu)建分布式系統(tǒng)中一些常見模式的工具(例如配置管理,服務(wù)發(fā)現(xiàn),斷路器,智...
    卡卡羅2017閱讀 136,680評(píng)論 19 139
  • 譯者說 Tornado 4.3于2015年11月6日發(fā)布,該版本正式支持Python3.5的async/await...
    TaoBeier閱讀 3,184評(píng)論 0 10
  • RequestHandler 1,利用HTTP協(xié)議向服務(wù)器傳參幾種途徑 1,查詢字符串(query string)...
    曉可加油閱讀 1,517評(píng)論 0 0
  • 2018年2月8日 晴 早晨吃了早飯,急急忙忙帶著孩子去上班,九點(diǎn)多又把程程和程一送到思倍兒家教月古箏和電子...
    A那年冬天閱讀 260評(píng)論 0 0
  • (三) 時(shí)光轉(zhuǎn)眼我們就大學(xué)畢業(yè)了,他在上海一家醫(yī)院實(shí)習(xí),我也在...
    心若幽蘭_3b4b閱讀 364評(píng)論 5 5

友情鏈接更多精彩內(nèi)容