2010-09-18 108 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): 
     ....