2010-09-18 5 views
21

Come ricevere JSON dalle richieste POST in CherryPy?Come ricevere JSON in una richiesta POST in CherryPy?

Sono stato a this page e anche se fa un buon lavoro spiegando l'API, i suoi parametri e quello che fa; Non riesco a capire come usarli per analizzare il JSON in arrivo in un oggetto.

Ecco quello che ho finora:



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) 

E, qui è la mia chiamata jQuery per rendere il palo


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 
    }; 
} 

risposta

27

esempio di lavoro:

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()) 

Il dottore si è collegato al descrive un paio di CherryPy Tools che sono nuovi nella versione 3.2. Lo strumento json_in fondamentalmente fa quanto sopra, con un po 'più rigore, e usando la nuova API di elaborazione del corpo in 3.2.

Una cosa importante da notare è che la funzione post di jQuery non sembra in grado di inviare JSON (solo a riceverlo). L'argomento dataType specifica il tipo di dati che ci si aspetta che XmlHTTPRequest a riceva, non il tipo che invierà e non sembra essere disponibile un argomento per specificare il tipo che si desidera inviare. L'utilizzo di ajax() invece consente di specificarlo.

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 per postare, è IMHO il modo più pulito per farlo. –

+0

'cherrypy.request' non ha attributo' json' – IAbstract

+2

@IAbstract controlla di avere il '' '' cherrypy.tools.json_in() '' 'decoratore. –

1

ho trovato il modo @cherrypy.tools.json_in() non molto pulito in quanto costringe l'uso cherrypy.request.json. Invece, il seguente decoratore tenta di simulare i parametri GET.

Quanto segue aiuta questo.

NOTA: Ciò presuppone che si desidera tornare 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 

esempio:

{"foo": "bar"} 

Get tradotto in

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