2010-09-18 26 views
21

¿Cómo recibir JSON de las solicitudes POST en CherryPy?¿Cómo recibir JSON en una solicitud POST en CherryPy?

He estado en this page, y aunque hace un buen trabajo explicando la API, sus parámetros y lo que hace; Parece que no puedo descifrar cómo usarlos para analizar el JSON entrante en un objeto.

Esto es lo que tengo hasta ahora:



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) 

Y, aquí está mi llamada jQuery para hacer el cargo


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

Respuesta

27

Ejemplo de trabajo:

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

El documento se ha vinculado a describe un par de herramientas CherryPy que son nuevas en la versión 3.2. La herramienta json_in básicamente hace lo anterior, con algo más de rigor, y usa la nueva API de procesamiento de cuerpo en 3.2.

Una cosa importante a tener en cuenta es que la función post de jQuery no parece poder enviar JSON (solo que la reciba). El argumento dataType especifica el tipo de datos que espera que XmlHTTPRequest a reciba, no el tipo que se enviará, y no parece haber un argumento disponible para que usted especifique el tipo que desea enviar. Usar ajax() en su lugar le permite especificar eso.

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 para que publique, es mi humilde opinión la manera más limpia para hacerlo. –

+0

'cherrypy.request' no tiene el atributo' json' – IAbstract

+2

@IAbstract comprueba que tienes el decorador '' '@ cherrypy.tools.json_in()' ''. –

1

He encontrado el camino @cherrypy.tools.json_in() no muy limpio ya que obliga a utilizar cherrypy.request.json. En cambio, el siguiente decorador intenta imitar los parámetros GET.

Lo siguiente ayuda a esto.

NOTA: Esto supone que desea volver 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 

ejemplo:

{"foo": "bar"} 

de traducirse en la

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