- 使用 Json
处理 JSON 请求
JSON 请求是一个以有效的 JSON 数据作为请求体的 HTTP 请求. 它必须指定 Content-Type
头为 text/json
或是 application/json
作为 mime 类型.
默认的, Action
使用 any content 作为 Body 解析器, 这让你接收 Body 并解析为 JSON (实际为 JsValue
):
1 2 3 4 5 6 7 8 9 10 11 |
def sayHello = Action { request => request.body.asJson.map { json => (json \ "name").asOpt[String].map { name => Ok("Hello " + name) }.getOrElse { BadRequest("Missing parameter [name]") } }.getOrElse { BadRequest("Expecting Json data") } } |
更好的(也是更简单的)办法是指定你自己的 BodyParser
用以告诉 Play 把类容 Body 直接解析为 JSON:
1 2 3 4 5 6 7 |
def sayHello = Action(parse.json) { request => (request.body \ "name").asOpt[String].map { name => Ok("Hello " + name) }.getOrElse { BadRequest("Missing parameter [name]") } } |
注: 让使用 JSON Body 解析器,
request.body
值就已经是一个有效的JsValue 了
.
你可以在命令行下用 cURL 进行测试:
1 2 3 4 5 |
curl --header "Content-type: application/json" --request POST --data '{"name": "Guillaume"}' http://localhost:9000/sayHello |
Unmi 注: curl 是 unix 簇系统下的命令,windows 下的 curl 当然也有,用法略有不同,在 Windows 下推荐用 Fiddler。上面命令在 shell 下换行的话需在每行后加上反斜杠 \,反斜杠的作用是把一个 shell 续行,所以需要在适当的地方加上空格,执行完命令就上下方向键看看刚刚执行的命令就知道,shell 知道把多行合成一行的。
回应是:
1 2 3 4 5 |
HTTP/1.1 200 OK Content-Type: text/plain; charset=utf-8 Content-Length: 15 Hello Guillaume |
Unmi 注: 在 Mac shell 下需给 curl 命令再加上 -i 才能看到响应头信息,否则只有 Hello Guillaume 行。如果用 -v 参数可以看到更详细的请求响应过程:
输出 JSON 响应
在我们前面的例子中处理了 JSON 请求, 但我们回应的是 text/plain
类型的数据. 让我们作点改变来向客户端送出有效的 JSON HTTP 响应数据:
1 2 3 4 5 6 7 8 9 10 11 |
def sayHello = Action(parse.json) { request => (request.body \ "name").asOpt[String].map { name => Ok(toJson( Map("status" -> "OK", "message" -> ("Hello " + name)) )) }.getOrElse { BadRequest(toJson( Map("status" -> "KO", "message" -> "Missing parameter [name]") )) } } |
Unmi 注: 使用 toJson() 方法需要引入 play.api.libs.json.Json._ 。play.libs.Json 也有个 toJson(Any),但它返回的是 JsonNode 类型,而我们要的是 JsValue 类型。
现在回应的是:
1 2 3 4 5 |
HTTP/1.1 200 OK Content-Type: application/json; charset=utf-8 Content-Length: 43 {"status":"OK","message":"Hello Guillaume"} |