Play Framework 2.5 ajax json路由参数异步MongoDB
在Play Framework中将json从javascript发布到服务器:Play Framework 2.5 ajax json路由参数异步MongoDB,json,ajax,routes,playframework-2.5,Json,Ajax,Routes,Playframework 2.5,在Play Framework中将json从javascript发布到服务器: var myJson = {"name": "joe", "age":20}; var obj = JSON.parse(myJson); $.ajax(jsRoutes.controllers.MyController.create(obj)); 现在,我已经很好地配置了javascript路由器。如果我以字符串形式接收obj,我可以将其打印到控制台上 routes.conf: POST /person
var myJson = {"name": "joe", "age":20};
var obj = JSON.parse(myJson);
$.ajax(jsRoutes.controllers.MyController.create(obj));
现在,我已经很好地配置了javascript路由器。如果我以字符串形式接收obj,我可以将其打印到控制台上
routes.conf:
POST /person/add controllers.MyController.createFromAjax(ajax: String)
但是,我想使用异步承诺将json写入MongoDB,Activator会给出编译时错误:
scala.concurrent.Future[play.api.mvc.Result][error] cannot be applied to (String)
我还有其他不带参数的路由,它们使用Postman接收json并将其写入MongoDB
routes.conf
POST /heartrates/bulk controllers.HRController.createFromJson
如果忽略从Ajax接收json的路由上的参数,而不是使用Postman,则浏览器中会出现HTTP 400错误
POST http://localhost:9000/person/add 400 (Bad Request)
所以,我的问题是,Ajax需要一个参数,但字符串不能工作。播放文档说json总是作为字符串接收。我做错了什么
Scala控制器代码取自Lightbend seed Play.Reactive.MongoDB:
def createBulkFromAjax = Action.async(parse.json) { request =>
val documents = for {
heartRate <- request.body.asOpt[JsArray].toStream
maybeHeartRate <- heartRate.value
validHeartRate <- maybeHeartRate.transform(transformer).asOpt.toList
} yield validHeartRate
for {
heartRate <- hrFuture
multiResult <- heartRate.bulkInsert(documents = documents, ordered = true)
} yield {
Logger.debug(s"Successfully inserted with multiResult: $multiResult")
Created(s"Created ${multiResult.n} heartRate")
}
}
def createBulkFromAjax=Action.async(parse.json){request=>
val文档=用于{
心率我认为您正在混淆作为jsRoutes
调用的一部分传递给Action
的参数和传递给端点的参数(即查询字符串、查询参数等)
如果您声明了一个非可选参数(就像您在ajax:String
中所做的那样),并且您没有在请求中实际提供它,Play将返回一个400错误请求
从概念上讲,您正在将obj
传递给您的操作,但它不是作为查询参数—您已经声明您的端点需要HTTP POST—因此JSON应该在HTTP请求正文中。请注意,您的其他端点不接受任何查询参数
因此步骤1是修复您的路由
文件(我已重命名您的方法以匹配其他现有工作方法):
如果查看,您会发现如果您正在执行GET以外的操作,则需要设置类型(也称为HTTP方法)。因此,步骤2,下面是实现POST的Javascript外观:
var myJson = {"name": "joe", "age":20};
var obj = JSON.stringify(myJson);
var r = controllers.MyController.createFromJson;
$.ajax({url: r.url, type: r.type, data: obj });
在这些更改之后,您应该很好;您的控制器代码看起来很好。如果您仍然收到400个错误请求
响应,请检查jQuery是否正确设置了内容类型
标题-您可能需要这样做
仍然收到400个错误后进行编辑:
我刚刚注意到您在Javascript中使用了JSON.parse
——您应该使用JSON.stringify
将对象转换为jQuery可以发送的内容——否则它可能会尝试对数据进行URL编码和/或将字段作为查询参数发送
另一个需要注意的问题是,您发送的JSON是否与您试图解析的内容一致。我不确定您是否提供了这个问题的简化版本,但看起来您正在尝试解析:
{"name": "joe", "age":20}
使用:
request.body.asOpt[JsArray]
这将始终导致一个无
-您没有给它一个数组。在CreativeMongo的Play Framework 2.5中对ajax javascript路由的回答:
routes.conf:
GET /javascriptRoutes controllers.HRController.javascriptRoutes
POST /heartrates/add controllers.HRController.createBulkFromAjax
人力资源控制员:
def javascriptRoutes = Action { implicit request =>
Ok(
JavaScriptReverseRouter("jsRoutes")(
routes.javascript.HRController.createBulkFromAjax
)
).as("text/javascript")
def createBulkFromAjax = Action.async(parse.json) { request =>
//Transformation silent in case of failures.
val documents = for {
heartRate <- request.body.asOpt[JsArray].toStream
maybeHeartRate <- heartRate.value
validHeartRate <- maybeHeartRate.transform(transformer).asOpt.toList
} yield validHeartRate
for {
heartRate <- hrFuture
multiResult <- heartRate.bulkInsert(documents = documents, ordered = true)
} yield {
Logger.debug(s"Successfully inserted with multiResult: $multiResult")
Created(s"Created ${multiResult.n} heartRate")
}
}
}
routes.conf:
GET /javascriptRoutes controllers.HRController.javascriptRoutes
POST /heartrates/add controllers.HRController.createBulkFromAjax
main.scala.html:
<script type="text/javascript" src="@routes.HRController.javascriptRoutes"></script>
人力资源控制员:
def javascriptRoutes = Action { implicit request =>
Ok(
JavaScriptReverseRouter("jsRoutes")(
routes.javascript.HRController.createBulkFromAjax
)
).as("text/javascript")
def createBulkFromAjax = Action.async(parse.json) { request =>
//Transformation silent in case of failures.
val documents = for {
heartRate <- request.body.asOpt[JsArray].toStream
maybeHeartRate <- heartRate.value
validHeartRate <- maybeHeartRate.transform(transformer).asOpt.toList
} yield validHeartRate
for {
heartRate <- hrFuture
multiResult <- heartRate.bulkInsert(documents = documents, ordered = true)
} yield {
Logger.debug(s"Successfully inserted with multiResult: $multiResult")
Created(s"Created ${multiResult.n} heartRate")
}
}
def createBulkFromAjax=Action.async(parse.json){request=>
//发生故障时,转换保持沉默。
val文档=用于{
心率您能给我们看一下您的控制器代码吗?添加了Scala控制器代码。我根据播放文档设置了jsrouter,所以javascript不会抱怨的唯一路由是:var r=jsRoutes.controllers.MyController.createFromJson();$.ajax({url:r.url,contentType:“application/json”,type:r.type,data:JsonObj});如上所述,我已将contentType参数添加到ajax中,但仍然得到错误400 jsrouter似乎工作正常:POST 400(错误请求)任何进一步的帮助都将不胜感激。谢谢。嘿嘿,这是有效的。我正在简化这个问题的代码,但我发现我的问题是route.conf中的一个重复路由,从我将json作为参数传递时开始。删除了路由,它可以与json.parse一起工作,也可以不与json.parse一起工作,因为我在方括号中进行了硬编码。我不知道stringify.T谢谢你的帮助@millhouse。我肯定我会有更多的问题要问。更正,你关于json.parse的说法是对的。我已经删除了它。它很有效。