2010-09-18 109 views
21

如何从CherryPy的POST请求中接收JSON?如何在CherryPy的POST请求中接收JSON?

我去过this page,尽管它很好地解释了API,它的参数以及它的功能;我似乎无法弄清楚如何使用它们将传入的JSON解析为对象。

这是我到目前为止有:



import cherrypy 
import json 

from web.models.card import card 
from web.models.session import getSession 
from web.controllers.error import formatEx, handle_error 

class CardRequestHandler(object): 

    @cherrypy.expose 
    def update(self, **jsonText): 
     db = getSession() 
     result = {"operation" : "update", "result" : "success" } 
     try: 
      u = json.loads(jsonText) 
      c = db.query(card).filter(card.id == u.id) 
      c.name = u.name 
      c.content = u.content 
      rzSession.commit() 
     except: 
      result["result"] = { "exception" : formatEx() } 
     return json.dumps(result) 

而且,这里是我的jQuery的征召令后


function Update(el){ 
    el = jq(el); // makes sure that this is a jquery object 

    var pc = el.parent().parent(); 
    pc = ToJSON(pc); 

    //$.ajaxSetup({ scriptCharset : "utf-8" }); 
    $.post("http://localhost/wsgi/raspberry/card/update", pc, 
      function(data){ 
       alert("Hello Update Response: " + data); 
      }, 
      "json"); 
} 

function ToJSON(h){ 
    h = jq(h); 
    return { 
     "id" : h.attr("id"), 
     "name" : h.get(0).innerText, 
     "content" : h.find(".Content").get(0).innerText 
    }; 
} 

回答

27

工作例如:

import cherrypy 
import simplejson 

class Root(object): 

    @cherrypy.expose 
    def update(self): 
     cl = cherrypy.request.headers['Content-Length'] 
     rawbody = cherrypy.request.body.read(int(cl)) 
     body = simplejson.loads(rawbody) 
     # do_something_with(body) 
     return "Updated %r." % (body,) 

    @cherrypy.expose 
    def index(self): 
     return """ 
<html> 
<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.4.2/jquery.min.js"></script> 
<script type='text/javascript'> 
function Update() { 
    $.ajax({ 
     type: 'POST', 
     url: "update", 
     contentType: "application/json", 
     processData: false, 
     data: $('#updatebox').val(), 
     success: function(data) {alert(data);}, 
     dataType: "text" 
    }); 
} 
</script> 
<body> 
<input type='textbox' id='updatebox' value='{}' size='20' /> 
<input type='submit' value='Update' onClick='Update(); return false' /> 
</body> 
</html> 
""" 

cherrypy.quickstart(Root()) 

您链接到该文档介绍了几个在3.2版本中新增的CherryPy工具。 json_in工具基本上完成了上述操作,并且使用了3.2中的新身体处理API。

需要注意的一件重要的事情是,jQuery的post函数似乎无法发送JSON(只接收它)。 dataType自变量指定您希望XmlHTTPRequest的数据类型为接收,而不是它将发送的类型,并且似乎没有可供您指定要发送的类型的参数。改用ajax()可以指定。

35

的Python

import cherrypy 
import simplejson 

class Root: 

    @cherrypy.expose 
    @cherrypy.tools.json_out() 
    @cherrypy.tools.json_in() 
    def my_route(self): 

     result = {"operation": "request", "result": "success"} 

     input_json = cherrypy.request.json 
     value = input_json["my_key"] 

     #All responses are serialized to JSON. This the same as 
     #return simplejson.dumps(result) 
     return result 

的JavaScript

//assuming that you're using jQuery 

var myObject = { "my_key": "my_value" }; 

$.ajax({ 
    type: "POST", 
    url: "my_route", 
    data: JSON.stringify(myObject), 
    contentType: 'application/json', 
    dataType: 'json', 
    error: function() { 
     alert("error"); 
    }, 
    success: function() { 
     alert("success"); 
    } 
}); 
+2

THX为您发布,这是恕我直言,最彻底的方法去做吧。 – 2013-09-25 11:10:08

+0

'cherrypy.request'没有属性'json' – IAbstract 2015-03-06 23:00:29

+2

@IAbstract检查你是否有'''@ cherrypy.tools.json_in()'''装饰器。 – 2015-06-10 12:19:39

1

我发现@cherrypy.tools.json_in()方式不是很干净,因为它强迫你使用cherrypy.request.json。相反,下面的装饰器试图模仿GET参数。

以下帮助。

注意:这假定你想返回JSON:

def uses_json(func): 

    @functools.wraps(func) 
    @cherrypy.tools.accept(media="application/json") 
    def wrapper(*args, **kwargs): 

     cherrypy.serving.response.headers['Content-Type'] = "application/json" 

     kwargs = dict(kwargs) 

     try: 
      body = cherrypy.request.body.read() 
      kwargs.update(json.loads(body)) 
     except TypeError: 
      pass 

     return json.dumps(func(*args, **kwargs)).encode('utf8') 

    return wrapper 

例如:

{"foo": "bar"} 

获取的翻译成

@cherypy.expose 
@uses_json 
def endpoint(foo): 
     ....