我一直用python2.x,python2.x内置的字符编码方式是unicode,这就对中文的处理造成了一些困扰,尤其是在用tornado写json接口的时候,如果不做处理,出来的没有中文,都是\x4d5f之类的东西。所以通常需要这样去处理下。
除了正常的
#!/usr/bin/env python
#coding: utf-8
之外
import sys
reload(sys)
sys.setdefaultencoding('utf-8')
是不可少的
另外,在做json.dumps的时候
self.write(response.body)
ensure_ascii=False需要有,才能正常的在json中显示中文。
这个是json包处理的问题而不是tornado处理的问题,self.write()中直接写中文则不会发生该问题。
关于tornado的httpclient异步回调功能,用一个简单的例子表达,访问baidu的IP地址查询库
class QueryIPHandler(tornado.web.RequestHandler):
@tornado.web.asynchronous
@tornado.gen.coroutine
def get(self, *args, **kwargs):
ip = self.get_argument('ip')
local_ip = self.request.headers['X-Real-IP']
conf = Config.get_config()
base_url = 'http://apis.baidu.com/apistore/iplookupservice/iplookup'
params = {}
params['ip'] = ip
try:
http = tornado.httpclient.AsyncHTTPClient()
headers = dict(self.request.headers)
headers['apikey'] = conf['BAIDU_APIKEY']
response = yield http.fetch(
tornado.httpclient.HTTPRequest(
url = base_url,
headers=headers,
method='POST',
body=json.dumps(params, ensure_ascii=False)
)
)
self.write(response.body)
except tornado.httpclient.HTTPError, e:
self.write(e)
使用web.asychronous修饰,使用gen.coroutine修饰,个人认为使用协程的好处是不用再写回调方法了。
base_url是需要访问百度api网址
params是请求参数,也就是query_string,
然后尝试使用tornado.httpclient.AsyncHTTPClient()
headers需要封装成字典类型并加入baidu的apikey。
response = yield http.fetch就是异步回调的"主体思想",用协程和yield方式就不需要像以前一样写回调函数了。
body参数按照tornado官方文档是字符串而非字典,所以要把params变量dumps成json串传过去。
http.fetch里的可配置参数项参考
http://www.tornadoweb.org/en/stable/httpclient.html
剩下的就是异常处理了。
为何要异步非阻塞?因为tornado是单进程的,如果不异步非阻塞的话,假如访问baidu很慢,则tornado进程会被卡住,访问tornado的其他页面也会卡在那里等待,直到百度访问完成,其他页面才会响应,所同理,node也是单进程的,天生就是异步非阻塞的。相比于node,我个人觉得tornado 的好处在于,想阻塞就阻塞,想非阻塞就非阻塞,很灵活,而node想写一个同步阻塞的应用就很麻烦了。
----20150815修订----
通过看源码得知,字符串处理可以使用tornado.escape,如tornado.escape.json_encode(dict),但是中文也会出现问题,tornado.escape内部对json_encode的处理也是对json包的二次封装,对于包含中文的内容,需要使用tornado.escape.json_encode(dict).decode('unicode_escape')处理就可以得到正确的结果。
不得不说,tornado的文档结构很好,就是说明台简单了,也缺少例子的支持,想深入了解,还是得自己看源码。
©著作权归作者所有:来自51CTO博客作者Slaytanic的原创作品,如需转载,请与作者联系,否则将追究法律责任