2017-02-19 18 views
0

POST ING JSON到服務器玩框架:從JavaScript播放框架2.5 AJAX JSON路線參數異步的MongoDB

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:

scala.concurrent.Future[play.api.mvc.Result][error] cannot be applied to (String) 

我有采取接收使用郵差和JSON無參數等航線它寫的MongoDB就好

​​3210

如果我省略從阿賈克斯接收,而不是使用郵差的JSON的路徑上的參數,我得到的兄弟一個HTTP 400錯誤wser。

POST http://localhost:9000/person/add 400 (Bad Request) 

所以,我的問題是,Ajax需要一個參數,但String不會工作。播放文檔說json總是以字符串形式接收。我在這裏做錯了什麼?

斯卡拉控制器從Lightbend種子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") 
} 
} 
+0

你能告訴我們你的控制器代碼嗎? – millhouse

+0

添加了Scala控制器代碼。 –

回答

0

我想你要傳遞給你的Action作爲jsRoutes調用的一部分參數,參數之間的混淆是傳遞給端點(即查詢字符串,查詢參數等)。

如果您聲明瞭非可選參數(如您對ajax: String所做的),並且您沒有在請求中實際提供該參數,則播放將返回400 Bad Request

雖然在概念上你傳遞obj到你的動作,它不是作爲查詢參數 - 你聲明,你的終點期望一個HTTP POST - 這樣的JSON應該在HTTP請求主體。注意你的其他端點不接受任何查詢參數。

所以第1步是修復您的routes文件(我已經改名爲你的方法,以配合您現有的其他工作之一):

POST /person/add  controllers.MyController.createFromJson 

如果你看一下Play documentation for the Javascript reverse router,你會看到如果你正在做的不是GET,你需要設置type(又名HTTP方法)。所以,第2步,這裏是你的Javascript應該是什麼樣子,實現了POST:

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 Bad Request迴應,請檢查jQuery是否正確設置你的Content-Type標題 - 你可能需要use the contentType option in the jQuery $.ajax call

後仍然得到400錯誤編輯:

我剛剛注意到,你在你的Javascript使用JSON.parse - as per this answer你應該使用JSON.stringify一個對象轉換成jQuery的東西可以送 - 否則可能嘗試URLEncode數據和/或發送字段作爲查詢參數。

另一個要看的是,你發送的JSON是否與你試圖解析的內容一致。我不知道,如果你已經爲這個問題提供了一個簡化版本,但它看起來像你試圖解析:

{"name": "joe", "age":20} 

使用:

request.body.asOpt[JsArray] 

哪樣總是結果一個None - 你沒有給它一個數組。

+0

我建立jsrouter按播放文檔,以便JavaScript的唯一路線犯規的是抱怨: VAR R = jsRoutes.controllers.MyController.createFromJson(); $就({URL:r.url,則contentType: 「應用程序/ JSON」,類型:r.type,數據:JsonObj}); 我已經加入的contentType參數去如上阿賈克斯,但仍然得到錯誤400 的jsrouter似乎工作正常生產: POST HTTP://本地主機:9000 /人/加400(錯誤請求)知道的任何進一步的幫助。謝謝。 –

+0

嘿,它工作。我爲這個問題簡化了我的代碼,但事實證明我的問題是從傳遞json作爲參數傳遞到route.conf中的一個重複路由。刪除了路由,它可以使用或不使用Json.parse,因爲我在方括號中進行了硬編碼。我不知道stringify。感謝您的幫助@millhouse。我相信我會有更多的問題來。 –

+0

更正,你對json.parse是正確的。我刪除了它。有用。 –

0

答案阿賈克斯播放框架2.5的JavaScript路線ReativeMongo:

routes.conf:

GET  /javascriptRoutes  controllers.HRController.javascriptRoutes 

HRController:

def javascriptRoutes = Action { implicit request => 
Ok(
    JavaScriptReverseRouter("jsRoutes")(
    routes.javascript.HRController.createBulkFromAjax 
) 
).as("text/javascript") 

}

routes.conf:

POST /heartrates/add  controllers.HRController.createBulkFromAjax 

main.scala.html:

<script type="text/javascript" src="@routes.HRController.javascriptRoutes"></script> 

的javascript:

var r = jsRoutes.controllers.HRController.createBulkFromAjax(); 
$.ajax({url: r.url, type: r.type, contentType: "application/json", data: JsonString }); 

HRController:

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") 
} 
} 

HRController.createBulkFromAjax從名爲發揮Lightbend激活UI種子例如建.ReactiveMogno