相似的想法,不同的方式。这是代码:
class Xroute(tornado.web.RequestHandler):
def get(self,path):
Router().get(path,self)
def post(self,path):
Router().post(path,self)
class Router(object):
mapper={}
@classmethod
def route(cls,**deco):
def foo(func):
url = deco.get('url') or '/'
if url not in cls.mapper:
method = deco.get('method') or 'GET'
mapper_node = {}
mapper_node['method'] = method
mapper_node['call'] = func
cls.mapper[url] = mapper_node
return func
return foo
def get(self,path,reqhandler):
self.emit(path,reqhandler,"GET")
def post(self,path,reqhandler):
self.emit(path,reqhandler,"POST")
def emit(self,path,reqhandler,method_flag):
mapper = Router.mapper
for urlExp in mapper:
m = re.match('^'+urlExp+'$',path)
if m:
params = (reqhandler,)
for items in m.groups():
params+=(items,)
mapper_node = mapper.get(urlExp)
method = mapper_node.get('method')
if method_flag not in method:
raise tornado.web.HTTPError(405)
call = mapper_node.get('call')
try:
call(*params)
break
except Exception,e:
print e
raise tornado.web.HTTPError(500)
else:
raise tornado.web.HTTPError(404)
@Router.route(url=r"hello/([a-z]+)",method="GET")
def test(req, who):
#http://localhost:8888/hello/billy
req.write("Hi," + who)
@Router.route(url=r"greetings/([a-z]+)",method="GET|POST")
def test2(req, who):
#http://localhost:8888/greetings/rowland
test(req, who)
@Router.route(url=r"book/([a-z]+)/(\d+)",method="GET|POST")
def test3(req,categories,bookid):
#http://localhost:8888/book/medicine/49875
req.write("You are looking for a " + categories + " book\n"+"book No. " + bookid)
@Router.route(url=r"person/(\d+)",method="GET|POST")
def test4(req, personid):
#http://localhost:8888/person/29772
who = req.get_argument("name","default")
age = req.get_argument("age",0)
person = {}
person['id'] = personid
person['who'] = who
person['age'] = int(age)
req.write(person)
if __name__=="__main__":
port = 8888
application = tornado.web.Application([(r"^/([^\.|]*)(?!\.\w+)$", Xroute),])
application.listen(port)
tornado.ioloop.IOLoop.instance().start()