Как получить 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
};
}
Ответы
Ответ 1
Рабочий пример:
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()
вместо этого позволяет вам указать это.
Ответ 2
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");
}
});
Ответ 3
Я нашел способ @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):
....