settings
前面的学习中,我们在创建tornado.web.Application的对象时,传入了第一个参数——路由映射列表。实际上Application类的构造函数还接收很多关于tornado web应用的配置参数
参数
debug设置
tornado是否工作在调试模式,默认为False即工作在生产模式。当设置debug=True 后,tornado会工作在调试/开发模式
tornado为方便我们开发而提供了几种特性
使用debug参数的方法
<span class="hljs-keyword">import</span> tornado.web
app = tornado.web.Application([], debug=<span class="hljs-keyword">True</span>)
使用autoreload参数的方法
app = tornado.web.Application([
(<span class="hljs-string">r"/"</span>, IndexHandler),
],autoreload=<span class="hljs-keyword">True</span>)
路由映射
先前我们在构建路由映射列表的时候,使用的是二元元组,如:
[(r"/", IndexHandler),]对于这个映射列表中的路由,实际上还可以传入多个信息,如:
<span class="hljs-keyword">from</span> tornado.web <span class="hljs-keyword">import</span> url
[
(<span class="hljs-string">r"/"</span>, Indexhandler),
(<span class="hljs-string">r"/cpp/"</span>, ITHandler, {<span class="hljs-string">"subject"</span>:<span class="hljs-string">"c++"</span>}),
url(<span class="hljs-string">r"/python/"</span>, ITHandler, {<span class="hljs-string">"subject"</span>:<span class="hljs-string">"python"</span>}, name=<span class="hljs-string">"python_url"</span>)
]
url方法:指定URL和处理程序之间的映射。
对于路由中的字典,会传入到对应的RequestHandler的initialize()方法中
<span class="hljs-keyword">from</span> tornado.web <span class="hljs-keyword">import</span> RequestHandler
<span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">ITHandler</span><span class="hljs-params">(RequestHandler)</span>:</span>
<span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">initialize</span><span class="hljs-params">(self, subject)</span>:</span>
self.subject = subject
<span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">get</span><span class="hljs-params">(self)</span>:</span>
self.write(self.subject)
对于路由中的name字段,注意此时不能再使用元组,而应使用tornado.web.url来构建。name是给该路由起一个名字,可以通过调用RequestHandler.reverse_url(name)来获取该名子对应的url
<span class="hljs-keyword">import</span> tornado.web
<span class="hljs-keyword">import</span> tornado.ioloop
<span class="hljs-keyword">import</span> tornado.httpserver
<span class="hljs-keyword">import</span> tornado.options
<span class="hljs-keyword">from</span> tornado.options <span class="hljs-keyword">import</span> options, define
<span class="hljs-keyword">from</span> tornado.web <span class="hljs-keyword">import</span> url, RequestHandler
define(<span class="hljs-string">"port"</span>, default=<span class="hljs-number">8000</span>, type=int, help=<span class="hljs-string">"run server on the given port."</span>)
<span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">IndexHandler</span><span class="hljs-params">(RequestHandler)</span>:</span>
<span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">get</span><span class="hljs-params">(self)</span>:</span>
python_url = self.reverse_url(<span class="hljs-string">"python_url"</span>)
self.write(<span class="hljs-string">'<a href="https://www.zutuanxue.com/home/8/%s">python学科</a>'</span> %
python_url)
<span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">ITHandler</span><span class="hljs-params">(RequestHandler)</span>:</span>
<span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">initialize</span><span class="hljs-params">(self, subject)</span>:</span>
self.subject = subject
<span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">get</span><span class="hljs-params">(self)</span>:</span>
self.write(self.subject)
<span class="hljs-keyword">if</span> __name__ == <span class="hljs-string">"__main__"</span>:
tornado.options.parse_command_line()
app = tornado.web.Application([
(<span class="hljs-string">r"/"</span>, Indexhandler),
(<span class="hljs-string">r"/cpp"</span>, ITHandler, {<span class="hljs-string">"subject"</span>:<span class="hljs-string">"c++"</span>}),
url(<span class="hljs-string">r"/python"</span>, ITHandler, {<span class="hljs-string">"subject"</span>:<span class="hljs-string">"python"</span>}, name=<span class="hljs-string">"python_url"</span>)
],
debug = <span class="hljs-keyword">True</span>)
http_server = tornado.httpserver.HTTPServer(app)
http_server.listen(options.port)
tornado.ioloop.IOLoop.current().start()
重写 RequestHandler 的方法函数
对于一个请求的处理过程代码调用次序如下
initialize() 函数,这个函数的参数是 Application 配置中的关键字参数定义。(initialize 方法是 Tornado 1.1 中新添加的,旧版本中你需要重写 __init__ 以达到同样的目的) initialize 方法一般只是把传入的参数存到成员变量中,而不会产生一些输出或者调用像 send_error 之类的方法prepare()。无论使用了哪种 HTTP 方法,prepare 都会被调用到,因此这个方法通常会被定义在一个基类中,然后在子类中重用。prepare可以产生输出信息。如果它调用了finish(或send_error` 等函数),那么整个处理流程就此结束get()、post()、put() 等。如果 URL 的正则表达式模式中有分组匹配,那么相关匹配会作为参数传入方法。重写 initialize() 函数(会在创建RequestHandler对象后调用)
<span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">ProfileHandler</span><span class="hljs-params">(tornado.web.RequestHandler)</span>:</span>
<span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">initialize</span><span class="hljs-params">(self,database)</span>:</span>
self.database = database
<span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">get</span><span class="hljs-params">(self)</span>:</span>
self.write(<span class="hljs-string">"result:"</span> + self.database)
application = tornado.web.Application([
(<span class="hljs-string">r"/init"</span>, ProfileHandler, dict(database=<span class="hljs-string">"database"</span>))
])
下面主要讲解tornado.web.RequestHandler
利用HTTP协议向服务器传参有几种途径
tornado中提供了以下方法来获取请求的信息
说明:对于请求体中数据的要求同前 这两个方法最常用
使用
<span class="hljs-keyword">import</span> tornado.web
<span class="hljs-keyword">import</span> tornado.ioloop
<span class="hljs-keyword">import</span> tornado.httpserver
<span class="hljs-keyword">import</span> tornado.options
<span class="hljs-keyword">from</span> tornado.options <span class="hljs-keyword">import</span> options, define
<span class="hljs-keyword">from</span> tornado.web <span class="hljs-keyword">import</span> RequestHandler, MissingArgumentError
define(<span class="hljs-string">"port"</span>, default=<span class="hljs-number">8000</span>, type=int, help=<span class="hljs-string">"run server on the given port."</span>)
<span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">IndexHandler</span><span class="hljs-params">(RequestHandler)</span>:</span>
<span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">post</span><span class="hljs-params">(self)</span>:</span>
query_arg = self.get_query_argument(<span class="hljs-string">"a"</span>)
query_args = self.get_query_arguments(<span class="hljs-string">"a"</span>)
body_arg = self.get_body_argument(<span class="hljs-string">"a"</span>)
body_args = self.get_body_arguments(<span class="hljs-string">"a"</span>, strip=<span class="hljs-keyword">False</span>)
arg = self.get_argument(<span class="hljs-string">"a"</span>)
args = self.get_arguments(<span class="hljs-string">"a"</span>)
default_arg = self.get_argument(<span class="hljs-string">"b"</span>, <span class="hljs-string">"itcast"</span>)
default_args = self.get_arguments(<span class="hljs-string">"b"</span>)
<span class="hljs-keyword">try</span>:
missing_arg = self.get_argument(<span class="hljs-string">"c"</span>)
<span class="hljs-keyword">except</span> MissingArgumentError <span class="hljs-keyword">as</span> e:
missing_arg = <span class="hljs-string">"We catched the MissingArgumentError!"</span>
<span class="hljs-keyword">print</span> e
missing_args = self.get_arguments(<span class="hljs-string">"c"</span>)
rep = <span class="hljs-string">"query_arg:%s<br/>"</span> % query_arg
rep += <span class="hljs-string">"query_args:%s<br/>"</span> % query_args
rep += <span class="hljs-string">"body_arg:%s<br/>"</span> % body_arg
rep += <span class="hljs-string">"body_args:%s<br/>"</span> % body_args
rep += <span class="hljs-string">"arg:%s<br/>"</span> % arg
rep += <span class="hljs-string">"args:%s<br/>"</span> % args
rep += <span class="hljs-string">"default_arg:%s<br/>"</span> % default_arg
rep += <span class="hljs-string">"default_args:%s<br/>"</span> % default_args
rep += <span class="hljs-string">"missing_arg:%s<br/>"</span> % missing_arg
rep += <span class="hljs-string">"missing_args:%s<br/>"</span> % missing_args
self.write(rep)
<span class="hljs-keyword">if</span> __name__ == <span class="hljs-string">"__main__"</span>:
tornado.options.parse_command_line()
app = tornado.web.Application([
(<span class="hljs-string">r"/"</span>, IndexHandler),
])
http_server = tornado.httpserver.HTTPServer(app)
http_server.listen(options.port)
tornado.ioloop.IOLoop.current().start()

RequestHandler.request属性
说明:RequestHandler.request 对象存储了关于请求的相关信息
格式:self.request.属性名
{ "form_filename1":[<tornado.httputil.HTTPFile>, <tornado.httputil.HTTPFile>], "form_filename2":[<tornado.httputil.HTTPFile>,], ... }tornado.httputil.HTTPFile是接收到的文件对象
三个属性:
filename 文件的实际名字,与form_filename1不同,字典中的键名代表的是表单对应项的名字
body 文件的数据实体
content_type 文件的类型。 这三个对象属性可以像字典一样支持关键字索引,如request.files[“form_filename1”][0][“body”]
文件上传 (模板中讲解)
正则提取uri
说明
tornado中对于路由映射也支持正则提取uri,提取出来的参数会作为RequestHandler中对应请求方式的成员方法参数。若在正则表达式中定义了名字,则参数按名传递;若未定义名字,则参数按顺序传递。提取出来的参数会作为对应请求方式的成员方法的参数
示例
<span class="hljs-keyword">import</span> tornado.web
<span class="hljs-keyword">import</span> tornado.ioloop
<span class="hljs-keyword">import</span> tornado.httpserver
<span class="hljs-keyword">import</span> tornado.options
<span class="hljs-keyword">from</span> tornado.options <span class="hljs-keyword">import</span> options, define
<span class="hljs-keyword">from</span> tornado.web <span class="hljs-keyword">import</span> RequestHandler
define(<span class="hljs-string">"port"</span>, default=<span class="hljs-number">8000</span>, type=int, help=<span class="hljs-string">"run server on the given port."</span>)
<span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">IndexHandler</span><span class="hljs-params">(RequestHandler)</span>:</span>
<span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">get</span><span class="hljs-params">(self)</span>:</span>
self.write(<span class="hljs-string">"hello lucky"</span>)
<span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">SubjectCityHandler</span><span class="hljs-params">(RequestHandler)</span>:</span>
<span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">get</span><span class="hljs-params">(self, subject, city)</span>:</span>
self.write((<span class="hljs-string">"Subject: %s<br/>City: %s"</span> % (subject, city)))
<span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">SubjectDateHandler</span><span class="hljs-params">(RequestHandler)</span>:</span>
<span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">get</span><span class="hljs-params">(self, date, subject)</span>:</span>
self.write((<span class="hljs-string">"Date: %s<br/>Subject: %s"</span> % (date, subject)))
<span class="hljs-keyword">if</span> __name__ == <span class="hljs-string">"__main__"</span>:
tornado.options.parse_command_line()
app = tornado.web.Application([
(<span class="hljs-string">r"/"</span>, IndexHandler),
(<span class="hljs-string">r"/sub-city/(.+)/([a-z]+)"</span>, SubjectCityHandler), <span class="hljs-comment"># 无名方式</span>
(<span class="hljs-string">r"/sub-date/(?P<subject>.+)/(?P<date>\d+)"</span>, SubjectDateHandler), <span class="hljs-comment"># 命名方式</span>
])
http_server = tornado.httpserver.HTTPServer(app)
http_server.listen(options.port)
tornado.ioloop.IOLoop.current().start()
建议:提取多个值时最好用命名方式
write(chunk)
将chunk数据写到输出缓冲区
<span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">IndexHandler</span><span class="hljs-params">(RequestHandler)</span>:</span>
<span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">get</span><span class="hljs-params">(self)</span>:</span>
self.write(<span class="hljs-string">"hello lucky!"</span>)
多次写入
<span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">IndexHandler</span><span class="hljs-params">(RequestHandler)</span>:</span>
<span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">get</span><span class="hljs-params">(self)</span>:</span>
self.write(<span class="hljs-string">"lucky is a good man!"</span>)
self.write(<span class="hljs-string">"lucky is a good handsome man!"</span>)
self.write(<span class="hljs-string">"lucky is a lucky man!"</span>)
注意:write方法是写到缓冲区的,我们可以像写文件一样多次使用write方法不断追加响应内容,最终所有写到缓冲区的内容一起作为本次请求的响应输出
写入json数据
json.dumps
<span class="hljs-keyword">import</span> json
<span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">IndexHandler</span><span class="hljs-params">(RequestHandler)</span>:</span>
<span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">get</span><span class="hljs-params">(self)</span>:</span>
stu = {
<span class="hljs-string">"name"</span>: <span class="hljs-string">"lucky"</span>,
<span class="hljs-string">"age"</span>: <span class="hljs-number">18</span>,
<span class="hljs-string">"sex"</span>: <span class="hljs-string">'man'</span>,
}
stu_json = json.dumps(stu)
self.write(stu_json)
注意:实际上,我们可以不用自己手动去做json序列化,当write方法检测到我们传入的chunk参数是字典类型后,会自动帮我们转换为json字符串
write自动转换
<span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">IndexHandler</span><span class="hljs-params">(RequestHandler)</span>:</span>
<span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">get</span><span class="hljs-params">(self)</span>:</span>
stu = {
<span class="hljs-string">"name"</span>: <span class="hljs-string">"lucky"</span>,
<span class="hljs-string">"age"</span>: <span class="hljs-number">18</span>,
<span class="hljs-string">"sex"</span>: <span class="hljs-string">'man'</span>,
}
self.write(stu)
区别
Content-Type字段,自己手动序列化时为Content-Type:text/html; charset=UTF-8,而采用write方法时为Content-Type:application/json; charset=UTF-8write方法除了帮我们将字典转换为json字符串之外,还帮我们将Content-Type设置为application/json; charset=UTF-8
关于Content-Type几种值的区别及用法
Content-Type 的值类型:
application/json 和 application/x-www-form-urlencoded的区别
application/x-www-form-urlencoded:信息数据被编码为名称/值对,这是标准且默认的编码格式
总结:
如果响应类型为 application/json 那么服务器会自动解析 那么到前端的时候就不需要再次解析 直接使用就可以 就和Django和flask中的 JsonHttpresponse和jsonify的作用一样
设置响应头 set_header(name, value)
说明:利用set_header(name, value)方法,可以手动设置一个名为name、值为value的响应头header字段
用set_header方法来实现write设置响应头
<span class="hljs-keyword">import</span> json
<span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">IndexHandler</span><span class="hljs-params">(RequestHandler)</span>:</span>
<span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">get</span><span class="hljs-params">(self)</span>:</span>
stu = {
<span class="hljs-string">"name"</span>: <span class="hljs-string">"lucky"</span>,
<span class="hljs-string">"age"</span>: <span class="hljs-number">18</span>,
<span class="hljs-string">"sex"</span>: <span class="hljs-string">'man'</span>,
}
stu_json = json.dumps(stu)
self.write(stu_json)
self.set_header(<span class="hljs-string">"Content-Type"</span>, <span class="hljs-string">"application/json; charset=UTF-8"</span>)
set_default_headers()
说明:该方法会在进入HTTP处理方法前先被调用,可以重写此方法来预先设置默认的headers
注意:在HTTP处理方法中使用set_header()方法会覆盖掉在set_default_headers()方法中设置的同名header
<span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">IndexHandler</span><span class="hljs-params">(RequestHandler)</span>:</span>
<span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">set_default_headers</span><span class="hljs-params">(self)</span>:</span>
print(<span class="hljs-string">"执行了set_default_headers()"</span>)
<span class="hljs-comment"># 设置get与post方式的默认响应体格式为json</span>
self.set_header(<span class="hljs-string">"Content-Type"</span>, <span class="hljs-string">"application/json; charset=UTF-8"</span>)
<span class="hljs-comment"># 设置一个名为lucky、值为is a good man的header</span>
self.set_header(<span class="hljs-string">"lucky"</span>, <span class="hljs-string">"is a good man"</span>)
<span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">get</span><span class="hljs-params">(self)</span>:</span>
print(<span class="hljs-string">"执行了get()"</span>)
stu = {
<span class="hljs-string">"name"</span>: <span class="hljs-string">"lucky"</span>,
<span class="hljs-string">"age"</span>: <span class="hljs-number">18</span>,
<span class="hljs-string">"sex"</span>: <span class="hljs-string">'man'</span>,
}
stu_json = json.dumps(stu)
self.write(stu_json)
self.set_header(<span class="hljs-string">"lucky"</span>, <span class="hljs-string">"is a handsome man"</span>) <span class="hljs-comment"># 注意此处重写了header中的lucky字段</span>
<span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">post</span><span class="hljs-params">(self)</span>:</span>
print(<span class="hljs-string">"执行了post()"</span>)
stu = {
<span class="hljs-string">"name"</span>: <span class="hljs-string">"lucky"</span>,
<span class="hljs-string">"age"</span>: <span class="hljs-number">18</span>,
<span class="hljs-string">"sex"</span>: <span class="hljs-string">'man'</span>,
}
stu_json = json.dumps(stu)
self.write(stu_json)
终端中打印出的执行

get请求方式的响应header

post请求方式的响应header

set_status(status_code, reason=None)
说明:为响应设置状态码
参数说明
HTTP协议常用标准状态码含义
状态码 | 含义 | 备注 |
|---|---|---|
200 | 请求已完成 | 2XX状态码均为正常状态码返回。 |
300 | 多种选择 | 服务器根据请求可执行多种操作。服务器可根据请求者 (User agent) 来选择一项操作,或提供操作列表供请求者选择。 |
301 | 永久移动 | 请求的网页已被永久移动到新位置。服务器返回此响应(作为对 GET 或 HEAD 请求的响应)时,会自动将请求者转到新位置。您应使用此代码通知 Googlebot 某个网页或网站已被永久移动到新位置。 |
302 | 临时移动 | 服务器目前正从不同位置的网页响应请求,但请求者应继续使用原有位置来进行以后的请求。此代码与响应 GET 和 HEAD 请求的 301 代码类似,会自动将请求者转到不同的位置。 |
303 | 查看其他位置 | 当请求者应对不同的位置进行单独的 GET 请求以检索响应时,服务器会返回此代码。对于除 HEAD 请求之外的所有请求,服务器会自动转到其他位置。 |
304 | 未修改 | 自从上次请求后,请求的网页未被修改过。服务器返回此响应时,不会返回网页内容。 |
305 | 使用代理 | 请求者只能使用代理访问请求的网页。如果服务器返回此响应,那么,服务器还会指明请求者应当使用的代理。 |
400 | 错误请求 | 服务器不理解请求的语法。 |
401 | 未授权 | 请求要求进行身份验证。登录后,服务器可能会对页面返回此响应。 |
403 | 已禁止 | 服务器拒绝请求。 |
404 | 未找到 | 服务器找不到请求的网页。例如,如果请求是针对服务器上不存在的网页进行的,那么,服务器通常会返回此代码。 |
405 | 方法禁用 | 禁用请求中所指定的方法。 |
406 | 不接受 | 无法使用请求的内容特性来响应请求的网页。 |
407 | 需要代理授权 | 此状态代码与401(未授权)类似,但却指定了请求者应当使用代理进行授权。如果服务器返回此响应,那么,服务器还会指明请求者应当使用的代理。 |
408 | 请求超时 | 服务器等候请求时超时。 |
409 | 冲突 | 服务器在完成请求时发生冲突。服务器的响应必须包含有关响应中所发生的冲突的信息。服务器在响应与前一个请求相冲突的PUT请求时可能会返回此代码,同时会提供两个请求的差异列表。 |
411 | 需要有效长度 | 服务器不会接受包含无效内容长度标头字段的请求。 |
412 | 未满足前提条件 | 服务器未满足请求者在请求中设置的其中一个前提条件。 |
413 | 请求实体过大 | 服务器无法处理请求,因为请求实体过大,已超出服务器的处理能力。 |
414 | 请求的URI过长 | 请求的URI(通常为网址)过长,服务器无法进行处理。 |
415 | 不支持的媒体类型 | 请求的格式不受请求页面的支持。 |
416 | 请求范围不符合要求 | 如果请求是针对网页的无效范围进行的,那么,服务器会返回此状态代码。 |
417 | 未满足期望值 | 服务器未满足期望请求标头字段的要求。 |
499 | 客户端断开连接 | 因服务端处理时间过长,客户端关闭了连接。 |
500 | 服务器内部错误 | 服务器遇到错误,无法完成请求。 |
501 | 尚未实施 | 服务器不具备完成请求的功能。例如,当服务器无法识别请求方法时,服务器可能会返回此代码。 |
502 | 错误网关 | 服务器作为网关或代理,从上游服务器收到了无效的响应。 |
503 | 服务不可用 | 目前无法使用服务器(由于超载或进行停机维护)。通常,这只是一种暂时的状态。 |
504 | 网关超时 | 服务器作为网关或代理,未及时从上游服务器接收请求。 |
505 | HTTP版本不受支持 | 服务器不支持请求中所使用的HTTP协议版本。 |
示例
<span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">Err404Handler</span><span class="hljs-params">(RequestHandler)</span>:</span>
<span class="hljs-string">"""对应/err/404"""</span>
<span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">get</span><span class="hljs-params">(self)</span>:</span>
self.write(<span class="hljs-string">"hello Lucky"</span>)
self.set_status(<span class="hljs-number">404</span>) <span class="hljs-comment"># 标准状态码,不用设置reason</span>
<span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">Err210Handler</span><span class="hljs-params">(RequestHandler)</span>:</span>
<span class="hljs-string">"""对应/err/210"""</span>
<span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">get</span><span class="hljs-params">(self)</span>:</span>
self.write(<span class="hljs-string">"hello lucky"</span>)
self.set_status(<span class="hljs-number">210</span>, <span class="hljs-string">"lucky error"</span>) <span class="hljs-comment"># 非标准状态码,设置了reason</span>
<span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">Err211Handler</span><span class="hljs-params">(RequestHandler)</span>:</span>
<span class="hljs-string">"""对应/err/211"""</span>
<span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">get</span><span class="hljs-params">(self)</span>:</span>
self.write(<span class="hljs-string">"hello lucky"</span>)
self.set_status(<span class="hljs-number">211</span>) <span class="hljs-comment"># 非标准状态码,未设置reason,错误</span>
请求结果



redirect(url)
说明:重定向 服务器直接跳转
示例
<span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">IndexHandler</span><span class="hljs-params">(RequestHandler)</span>:</span>
<span class="hljs-string">"""对应/"""</span>
<span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">get</span><span class="hljs-params">(self)</span>:</span>
self.write(<span class="hljs-string">"主页"</span>)
<span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">LoginHandler</span><span class="hljs-params">(RequestHandler)</span>:</span>
<span class="hljs-string">"""对应/login"""</span>
<span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">get</span><span class="hljs-params">(self)</span>:</span>
self.write(<span class="hljs-string">'<form method="post"><input type="submit" value="登陆"></form>'</span>)
<span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">post</span><span class="hljs-params">(self)</span>:</span>
self.redirect(<span class="hljs-string">"/"</span>) <span class="hljs-comment"># 重定向到首页</span>
send_error(status_code=500, **kwargs)
说明:抛出HTTP错误状态码status_code,默认为500,kwargs为可变命名参数。使用send_error抛出错误后tornado会调用write_error()方法进行处理,并返回给浏览器处理后的错误页面
示例
<span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">IndexHandler</span><span class="hljs-params">(RequestHandler)</span>:</span>
<span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">get</span><span class="hljs-params">(self)</span>:</span>
self.write(<span class="hljs-string">"主页"</span>)
self.send_error(<span class="hljs-number">404</span>, content=<span class="hljs-string">"出现404错误"</span>)
注意:默认的write_error()方法不会处理send_error抛出的kwargs参数,即上面的代码中content="出现404错误"是没有意义的
继续使用write方法
<span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">IndexHandler</span><span class="hljs-params">(RequestHandler)</span>:</span>
<span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">get</span><span class="hljs-params">(self)</span>:</span>
self.write(<span class="hljs-string">"主页"</span>)
self.send_error(<span class="hljs-number">404</span>, content=<span class="hljs-string">"出现404错误"</span>)
self.write(<span class="hljs-string">"结束"</span>) <span class="hljs-comment"># 我们在send_error再次向输出缓冲区写内容</span>
注意:使用send_error()方法后就不会再向输出缓冲区写内容了
write_error(status_code, **kwargs)
说明:用来处理send_error抛出的错误信息并返回给浏览器错误信息页面。可以重写此方法来定制自己的错误显示页面
示例
<span class="hljs-keyword">import</span> tornado.web
<span class="hljs-keyword">import</span> tornado.ioloop
<span class="hljs-keyword">from</span> tornado.web <span class="hljs-keyword">import</span> RequestHandler
<span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">IndexHandler</span><span class="hljs-params">(RequestHandler)</span>:</span>
<span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">get</span><span class="hljs-params">(self)</span>:</span>
self.write(<span class="hljs-string">"主页"</span>)
self.send_error(<span class="hljs-number">404</span>, content=<span class="hljs-string">"出现404错误"</span>)
self.write(<span class="hljs-string">"结束"</span>) <span class="hljs-comment"># 我们在send_error再次向输出缓冲区写内容</span>
<span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">write_error</span><span class="hljs-params">(self, status_code, **kwargs)</span>:</span>
self.write(<span class="hljs-string">"<h1>出错了,程序员GG正在赶过来!</h1>"</span>)
self.write(<span class="hljs-string">"<p>错误名:%s</p>"</span> % kwargs[<span class="hljs-string">"title"</span>])
self.write(<span class="hljs-string">"<p>错误详情:%s</p>"</span> % kwargs[<span class="hljs-string">"content"</span>])
<span class="hljs-keyword">if</span> __name__ == <span class="hljs-string">"__main__"</span>:
app = tornado.web.Application([
(<span class="hljs-string">r"/"</span>, IndexHandler),
])
app.listen(<span class="hljs-number">8000</span>)
tornado.ioloop.IOLoop.current().start()
结果

initialize()
说明:对应每个请求的处理类Handler在构造一个实例后首先执行initialize()方法
在讲输入时说过,路由映射中的第三个字典型参数会作为该方法的命名参数传递
如:
<span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">ProfileHandler</span><span class="hljs-params">(RequestHandler)</span>:</span>
<span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">initialize</span><span class="hljs-params">(self, database)</span>:</span>
self.database = database
<span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">get</span><span class="hljs-params">(self)</span>:</span>
...
app = Application([
(<span class="hljs-string">r'/user/(.*)'</span>, ProfileHandler, dict(database=database)),
])
注意:此方法通常用来初始化参数(对象属性),很少使用
prepare()
说明:预处理,即在执行对应请求方式的HTTP方法(如get、post等)前先执行
注意:不论以何种HTTP方式请求,都会执行prepare()方法
以预处理请求体中的json数据为例:
<span class="hljs-keyword">import</span> json
<span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">IndexHandler</span><span class="hljs-params">(RequestHandler)</span>:</span>
<span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">prepare</span><span class="hljs-params">(self)</span>:</span>
<span class="hljs-keyword">if</span> self.request.headers.get(<span class="hljs-string">"Content-Type"</span>).startswith(<span class="hljs-string">"application/json"</span>):
self.json_dict = json.loads(self.request.body)
<span class="hljs-keyword">else</span>:
self.json_dict = <span class="hljs-keyword">None</span>
<span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">post</span><span class="hljs-params">(self)</span>:</span>
<span class="hljs-keyword">if</span> self.json_dict:
<span class="hljs-keyword">for</span> key, value <span class="hljs-keyword">in</span> self.json_dict.items():
self.write(<span class="hljs-string">"<h3>%s</h3><p>%s</p>"</span> % (key, value))
<span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">put</span><span class="hljs-params">(self)</span>:</span>
<span class="hljs-keyword">if</span> self.json_dict:
<span class="hljs-keyword">for</span> key, value <span class="hljs-keyword">in</span> self.json_dict.items():
self.write(<span class="hljs-string">"<h3>%s</h3><p>%s</p>"</span> % (key, value))
用post方式发送json数据时

用put方式发送json数据时
方法 | 描述 |
|---|---|
get | 请求指定的页面信息,并返回实体主体。 |
head | 类似于get请求,只不过返回的响应中没有具体的内容,用于获取报头 |
post | 向指定资源提交数据进行处理请求(例如提交表单或者上传文件)。数据被包含在请求体中。POST请求可能会导致新的资源的建立和/或已有资源的修改。 |
delete | 请求服务器删除指定的内容。 |
patch | 请求修改局部数据。 |
put | 从客户端向服务器传送的数据取代指定的文档的内容。 |
options | 返回给定URL支持的所有HTTP方法。 |
on_finish()
在请求处理结束后调用,即在调用HTTP方法后调用。通常该方法用来进行资源清理释放或处理日志等
注意:请尽量不要在此方法中进行响应输出
set_default_headers()
write_error()
调用顺序
示例
<span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">IndexHandler</span><span class="hljs-params">(RequestHandler)</span>:</span>
<span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">initialize</span><span class="hljs-params">(self)</span>:</span>
print(<span class="hljs-string">"调用了initialize()"</span>)
<span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">prepare</span><span class="hljs-params">(self)</span>:</span>
print(<span class="hljs-string">"调用了prepare()"</span>)
<span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">set_default_headers</span><span class="hljs-params">(self)</span>:</span>
print(<span class="hljs-string">"调用了set_default_headers()"</span>)
<span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">write_error</span><span class="hljs-params">(self, status_code, **kwargs)</span>:</span>
print(<span class="hljs-string">"调用了write_error()"</span>)
<span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">get</span><span class="hljs-params">(self)</span>:</span>
print(<span class="hljs-string">"调用了get()"</span>)
<span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">post</span><span class="hljs-params">(self)</span>:</span>
print(<span class="hljs-string">"调用了post()"</span>)
self.send_error(<span class="hljs-number">200</span>) <span class="hljs-comment"># 注意此出抛出了错误</span>
<span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">on_finish</span><span class="hljs-params">(self)</span>:</span>
print(<span class="hljs-string">"调用了on_finish()"</span>)

在正常情况未抛出错误时,调用顺序为:
在有错误抛出时,调用顺序为: