Как получить JSON в POST-запросе в CherryPy?

Как получить JSON из запросов POST в CherryPy?

Я был на этой странице, и хотя она хорошо работает объяснение 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
    };
}

person bitcycle    schedule 18.09.2010    source источник


Ответы (3)


Рабочий пример:

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

Документ, на который вы ссылаетесь, описывает несколько инструментов CherryPy, которые являются новыми в версии 3.2. Инструмент json_in в основном делает то же самое, но с большей точностью и с использованием нового API обработки тела в версии 3.2.

Важно отметить, что функция jQuery post, похоже, не может отправлять JSON (только получать его). Аргумент dataType указывает тип данных, которые вы ожидаете, что XmlHTTPRequest получит, а не тип, который он будет отправлять, и, похоже, у вас нет доступного аргумента для указания типа, который вы хотите отправить. . Использование вместо этого ajax() позволяет указать это.

person fumanchu    schedule 20.09.2010

Питон

import cherrypy

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"]

        # Responses are serialized to JSON (because of the json_out decorator)
        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");
    }
});
person btsuhako    schedule 21.08.2013
comment
cherrypy.request не имеет атрибута json - person IAbstract; 07.03.2015
comment
@IAbstract убедитесь, что у вас есть декоратор @cherrypy.tools.json_in(). - person Stefan Krüger; 10.06.2015

Я нашел способ @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"}

переводится на

 class Root(object): 
     ...
 
     @cherrypy.expose
     @uses_json
     def endpoint(self, foo):
         ....
person Serguei Fedorov    schedule 20.11.2017
comment
На самом деле это довольно интересный подход. Не могли бы вы немного объяснить, почему вы объединяете kwargs с json в теле ответа? Если все ожидается от json, какие параметры будут в качестве kwargs? - person Jinghui Niu; 26.09.2020