[tornado]入门tornado(2): Handler
Handler是tornado编程中很重要的一环, tornado应用中几乎每一个页面都对应至少一个handler, handler控制着应用后台的业务逻辑
Handler
handler的接口大致可以分为3类 -- 输入, 输出, 流程
input
如何解析前台传来的参数
https://www.tornadoweb.org/en/stable/web.html#input
前台传来的参数/数据包括url参数(query param)和表单参数(form param, json格式), 一般来说存在以下接口:
get_argument(s)
先从post的form(无header)中解析参数, 如果form中没有, 会从url中解析
get_body_argument(s)
解析form(有header)里的参数(json格式数据)
class JsonWithFormHeadersParamHandler(web.RequestHandler):
async def post(self):
name = self.get_body_argument("name")
age = self.get_body_argument("age")
self.write("name: {}, age: {}".format(name, age))
get_query_argument(s)
解析url带来的参数
class UrlParamHandler(web.RequestHandler):
async def get(self):
name = self.get_query_argument("name")
age = self.get_query_argument("age")
self.write("name: {}, age: {}".format(name, age))
self.write('<br/>')
names = self.get_query_arguments("name")
ages = self.get_query_arguments("age")
self.write("names: {}, ages: {}".format(names, ages))
假设url传入参数 name=ana&&age=20&&name=bob&&age=28
name: bob, age: 28
names: ['ana', 'bob'], ages: ['20', '28']
其它类型的参数
比如json格式的参数, 使用request.body, 代码演示具体可以看看 iworkh/tornado/handler/input
有无s的区别
没有s的: 接受两个参数(name和default), 如果default未指定, 则name指代的参数是必须的, 如果丢失会报错; 如果参数传入多次, 则选择最后一次传入的值
有s的: 接受并返回数组格式, 如果传入参数为空, 也会返回空数组
output
https://www.tornadoweb.org/en/stable/web.html#output 建议看这里, 更细致
set_status: 设置状态码
write: 写数据,可以write多次,放缓存中,而不会中断当flush或者finish或者没消息断开时发送
flush: 刷新数据到客户端
finish: 写数据,写完断开了
render/render_string: 模板方式渲染输出
redirect: 重定向
send_error/write_error: 发送错误
render_embed_js/render_embed_css: 嵌入的js和css
render_linked_js/render_linked_css: 链接的js和css
render_xxx和template有关
class OutputDemoHandler(web.RequestHandler):
async def get(self):
self.set_status(200)
self.write("error!!!")
self.write("warning!!!")
self.write("<br/>")
await self.flush()
await asyncio.sleep(5)
self.write("success!!!")
await self.finish("done")
结果是先打印error和warning, 然后换行, 因为flush刷新了数据; 接着5秒过后, 再打印success和done
process
和很多类对象一样, handler也有一个类似生命周期的东西
initialize: 初始化,通过
URLSpec
可将参数传递到方法
prepare: 在get/post等操作之前,会调用
get/head/post/delete/patch/put/options: 一般业务逻辑处理
on_finish: 在out操作之后,会调用
需要注意的几个点
- 顺序是 initialize -> prepare -> 一堆函数 -> on_finish
- initialize需要的参数可以通过Application的handlers域传入 -- 在上一篇tornado学习里也提到过
# 先定义一个类和initialize方法
class ProcessDemoHandler(web.RequestHandler):
# initialize方法同步
def initialize(self, dbinfo):
print("initialize...")
self.dbinfo = dbinfo
print("数据库host:{}".format(self.dbinfo['db_host']))
pass
# 这里是需要传入initialize的参数
init_param = {
'dbinfo': {
'db_host': 'localhost',
'db_port': 3306,
'db_user': 'root',
'db_password': '123',
}
}
# 程序入口
if __name__ == '__main__':
app = web.Application(
[
(r"/?", ProcessDemoHandler, init_param),
],
debug=True
)
# ...
其他的handler以及模板
都在这里了 https://www.tornadoweb.org/en/stable/web.html#everything-else
cookie和application
Cookies: https://www.tornadoweb.org/en/stable/web.html#cookies
Application: https://www.tornadoweb.org/en/stable/web.html#application-configuration