Tornado输入与输出

输出

write方式

前面介绍基本的输出,可以通过write把字符串输出到浏览器,除此之外,write还可以把那些东西输出到浏览器呢?

  1. 字节bytes
self.write(b'Tornado<br/>')  #bytes 字节
  1. 字典dict
user = {'name':'cainiao','age':18}  #字典
self.write(user)   #字典
  1. 字符Unicode
 self.write('22<br/>33')
  1. 其他
li = [1,2,3,4]
import json

li = json.dumps(li)  #列表,需要序列化成json字符
self.write(li)
代码实例
import tornado.httpserver
import tornado.ioloop
import tornado.options
import tornado.web

from tornado.options import define,options

define('port', default=8080, help='run port', type=int)

class TestHandler(tornado.web.RequestHandler):
    def get(self):
        self.write(b'Tornado<br/>')  #bytes 字节
        user = {'name':'cainiao','age':18}  #字典
        print(user)
        print(repr(user))
        self.write('22<br/>33')

        self.write(user)   #字典,如果输出有个是字典,那么其他一并当做json格式输出,所以上面那个<br/>会失效显示出来,

        li = [1,2,3,4]
        import json

        li = json.dumps(li)  #列表,需要序列化成json字符
        print(li)
        print(repr(li))
        self.write(li)
        li = json.loads(li) #反序列
        print(li)
        print(repr(li))

application = tornado.web.Application(
    handlers = [
        (r'/test',TestHandler),
    ],
    debug = True   #调试模式,修改后自动重启服务,不需要自动重启,生产情况下切勿开启,安全性
)


if __name__ == '__main__':
    tornado.options.parse_command_line()
    http_server = tornado.httpserver.HTTPServer(application)
    http_server.listen(options.port)
    tornado.ioloop.IOLoop.instance().start()

运行结果:
image.png

注意:上面<br/>标签失效,显示出来了,这是为什么呢?
解答:按照源码write方法解释

image.png

意思是如果给定的是字典形式,会将其转化为json格式和设置响应头为application/json格式,所以代码中几个write方法中,只有有一个为字典就都会转化!

总结:
1、write可以接受 bytes、unicode字符和字典这个三个对象;
2、如果接受的是字典,会把字典转化成 JSON 字符串,因此write也可以接受 JSON 字符串。所以对于其他的可以先转换成json格式。

缓冲区flush

write 会先把内容放在缓冲区,正常情况下,当请求处理完成后会自动把缓冲区的内容输出到浏览器,但是可以调用 flush 方法,这样可以直接把缓冲区的内容输出到浏览器,不用等待请求处理完成,这就可能先看到flush前面部分内容,后面部分内容等请求处理完才能看到。


image.png
代码实例
import tornado.httpserver
import tornado.ioloop
import tornado.options
import tornado.web

from tornado.options import define,options

define('port', default=8080, help='run port', type=int)

class TestHandler(tornado.web.RequestHandler):
    def get(self):
        self.write(b'Tornado<br/>')  #bytes 字节
        user = {'name':'cainiao','age':18}  #字典
        print(user)
        print(repr(user))
        self.write('22<br/>33')

        self.flush()  #这样可以直接把缓冲区的内容输出到浏览器,不用等待请求处理完成,

        import time
        time.sleep(6) #通过sleep暂停几秒好验证一般write一次性全部刷到客户端去

        self.write(user)   #字典,如果输出有个是字典,那么其他一并当做json格式输出,所以上面那个<br/>会失效显示出来,


        li = [1,2,3,4]
        import json

        li = json.dumps(li)  #列表,需要序列化成json字符
        print(li)
        print(repr(li))
        self.write(li)
        li = json.loads(li) #反序列
        print(li)
        print(repr(li))

application = tornado.web.Application(
    handlers = [
        (r'/test',TestHandler),
    ],
    debug = True   #调试模式,修改后自动重启服务,不需要自动重启,生产情况下切勿开启,安全性
)

if __name__ == '__main__':
    tornado.options.parse_command_line()
    http_server = tornado.httpserver.HTTPServer(application)
    http_server.listen(options.port)
    tornado.ioloop.IOLoop.instance().start()
运行结果

image.png

效果:可以在浏览器看到,刚开始输出flush前面部分,其他部分等请求处理完自动输出到浏览器中,sleep(6)休眠6秒钟主要是为了好验证看出效果。最终显示在浏览器的结果可以看出没有出现刚开始一样的<br/>原始标签,而是换行了,这是因为flush前面部分没有字典,所以响应的头部类型Content-Type:text/html;后面部分就算有字典不会再生成类型,一次请求资源只有一次生成。
如果将flush写到输出字典的后面部分

self.write(user) 
self.flush()

输出结果:


image.png

image.png

内容类型就会变成json格式。

render方式,Tornado返回一个html文件

self.render('index.html')
通过render可以返回一个 html 文件,想要 Tornado 能够正确的找到 html 文件,需要在 Application 中指定文件的位置

redirect方式,跳转路由,重定向

self.redirect(r'/index')
通过redirect可以跳转到指定的路由。

以上综合代码:

import tornado.httpserver
import tornado.ioloop
import tornado.options
import tornado.web

from tornado.options import define,options

define('port', default=8080, help='run port', type=int)

class IndexHandler(tornado.web.RequestHandler):
    def get(self):
        self.render('index.html')  #通过render可以返回一个 html 文件

class HomeHandleer(tornado.web.RequestHandler):
    def get(self):
        self.redirect(r'/index')

application = tornado.web.Application(
    handlers = [
        (r'/index',IndexHandler),
        (r'/home',HomeHandleer)
    ],
    template_path = 'templates', #想要Tornado能够正确的找到html文件,需要在 Application 中指定文件的位置
    debug = True   #调试模式,修改后自动重启服务,不需要自动重启,生产情况下切勿开启,安全性
)

if __name__ == '__main__':
    tornado.options.parse_command_line()
    http_server = tornado.httpserver.HTTPServer(application)
    http_server.listen(options.port)
    tornado.ioloop.IOLoop.instance().start()

返回html文件效果:


image.png

重定向效果:


image.png

image.png
结束请求

一般程序执行完结束,一次请求结束,当调用 finish 之后,请求处理完成,类似于函数中的 return (注意:请求当中不能出现return) ,其后不能再执行 write 、render、redirect,否则会报错。


image.png

前端看不出错误,后端报错:


image.png

获取请求信息

class IndexHandler(tornado.web.RequestHandler):
    def get(self):
        self.write(self.request.remote_ip)  #客户端ip
        self.write(self.request.full_url())  #请求url地址
        print(self.request.request_time()) #访问时间
        print(self.request.uri)  #请求路由
        print(self.request.path)  #请求路由

        #继承类  tornado.web.RequestHandler 之后,可以直接调用 self.request  来获取客户端请求信息
method HTTP请求方法,例如 GET 或 POST
remote_ip 客户端的IP地址,返回值类型为字符串
full_url() 重新构建此请求的完整URL
request_time() 返回此请求执行所花费的时间
uri 请求的完整uri
path 路径部分的uri
query 查询部分的uri
vertion 请求中指定的HTTP版本,例如“HTTP / 1.1”

总结:继承类tornado.web.RequestHandler之后,可以直接调用self.request来获取客户端请求信息。

输入

代码实例
import tornado.httpserver
import tornado.ioloop
import tornado.options
import tornado.web
from tornado.options import define,options

define('port', default=8080, help='run port', type=int)


class RegisterHandler(tornado.web.RequestHandler):

    def get(self):
        info = self.get_argument('info','')
        self.write(info)
        self.render('register.html')

    def post(self, *args, **kwargs):
        name = self.get_argument('name','')
        passwd = self.get_argument('password','')

        self.write(name)
        self.write('name:'+name+'<br/>')
        self.write('password:'+passwd)


application = tornado.web.Application(
    handlers = [
        (r'/register',RegisterHandler),
    ],
    template_path = 'templates', #想要Tornado能够正确的找到html文件,需要在 Application 中指定文件的位置
    debug = True   #调试模式,修改后自动重启服务,不需要自动重启,生产情况下切勿开启,安全性
)

if __name__ == '__main__':
    tornado.options.parse_command_line()
    http_server = tornado.httpserver.HTTPServer(application)
    http_server.listen(options.port)
    tornado.ioloop.IOLoop.instance().start()

image.png

image.png

image.png

image.png

由以上可以得出get_argumentget和post都可以获取对应参数。

  • 获取url数据,get_argument可以获取 URL (查询字符串)中的参数。
  • 获取body数据,get_argument可以获取body(请求体)中的数据。
  • get_argument返回的值始终是unicode。
其他输入了解
  • self.get_query_argument('name', 'query'),获取查询字符串中参数,即url中的。对应的也有:get_query_arguments。
  • self.get_body_argument('name', 'body'),获取 body 中的参数。对应的也有: get_body_arguments。

url传参

查询字符串风格

class RegisterHandler(tornado.web.RequestHandler):
    def get(self):
        info = self.get_argument('info','')
        self.write(info)
路由
 (r'/register',RegisterHandler)
URL

http://127.0.0.1:8000/register?info=please login at first

REST风格

handler
class LoginHandler(tornado.web.RequestHandler):
    def get(self, name, age):

        self.write('name:%s<br/>age:%s'%(name,age))
路由
(r'/login/(.+)/([0-9]+)',LoginHandler),  #正则写法,使用圆括号进行传参的时候是位置传参
(r'/login/(?P<name>.+)/(?P<age>[0-9]+)',LoginHandler) #命名组写法,使用关键字,路由与handler方法不一定顺序一致
URL
image.png
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 203,772评论 6 477
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,458评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,610评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,640评论 1 276
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,657评论 5 365
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,590评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,962评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,631评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,870评论 1 297
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,611评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,704评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,386评论 4 319
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,969评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,944评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,179评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 44,742评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,440评论 2 342

推荐阅读更多精彩内容