播放框架。在同一操作中接受 JSON 和表单提交
Play Framework. Accepting JSON and Form Submit on same action
我使用 Play Scala 框架编写了这个示例应用程序。 (TypeSafe 激活器)
Application.scala
package controllers
import play.api.mvc._
import models._
object Application extends Controller {
def index = Action {
Ok(views.html.main(Person.form))
}
def submit = Action { implicit request =>
Person.form.bindFromRequest().fold(
formWithErrors => BadRequest(views.html.main(formWithErrors)),
p => {
Ok(s"Hi ${p.firstname} ${p.lastname}")
}
)
}
}
Person.scala
package models
import play.api.data.Form
import play.api.data.Forms.{mapping, text, of}
import play.api.data.format.Formats.doubleFormat
import play.api.libs.json.{__, Reads, Writes}
import play.api.libs.functional.syntax._
import play.api.libs.json.Json
case class Person(firstname: String, lastname: String)
object Person {
val form = Form(mapping(
"firstname" -> text,
"lastname" -> text
)(Person.apply)(Person.unapply))
implicit val readsPerson: Reads[Person] = (
((__ \ "firstname").read[String]) and
((__ \ "lastname").read[String])
)(Person.apply _)
implicit val writesItem = Writes[Person] {
case Person(firstname, lastname) =>
Json.obj(
"firstname" -> firstname,
"lastname" -> lastname
)
}
}
现在这在浏览器中运行得非常好。
然而,当我尝试从 curl 调用操作时
curl -H "Content-Type: application/x-www-form-urlencoded" -X POST -d '{"firstname":"abhishek", "lastname":"srivastava"}' http://localhost:9000/
失败并显示冗长的 HTML 消息。
我的理解是,如果我使用 x-www-form-urlencoded,那么在 post 时,我可以接受来自 HTML 表单和 JSON请求。
我做错了什么吗?还是我的理解有问题?
基本上我想要相同的控制器方法 Action 来服务 json post 请求以及 html 表单提交。
简短回答:在客户端设置 Content-Type
header,在服务器端使用默认的 body 解析器,这一切都会像魔术一样工作! :) 将 Action(parse.urlFormEncoded)
替换为简单的 Action
,然后将使用默认解析器。
长答案:
默认解析器将根据 Content-Type
header 自动使用正确的解析器,无论是 application/x-www-form-urlencoded
、application/json
还是其他。
然后在您的 post
方法中,bindFromRequest
将检查所有物体以确定已设置的物体,无论是 asFormUrlEncoded
还是 asJson
,然后将其用于表单数据处理。
我使用 Play Scala 框架编写了这个示例应用程序。 (TypeSafe 激活器)
Application.scala
package controllers
import play.api.mvc._
import models._
object Application extends Controller {
def index = Action {
Ok(views.html.main(Person.form))
}
def submit = Action { implicit request =>
Person.form.bindFromRequest().fold(
formWithErrors => BadRequest(views.html.main(formWithErrors)),
p => {
Ok(s"Hi ${p.firstname} ${p.lastname}")
}
)
}
}
Person.scala
package models
import play.api.data.Form
import play.api.data.Forms.{mapping, text, of}
import play.api.data.format.Formats.doubleFormat
import play.api.libs.json.{__, Reads, Writes}
import play.api.libs.functional.syntax._
import play.api.libs.json.Json
case class Person(firstname: String, lastname: String)
object Person {
val form = Form(mapping(
"firstname" -> text,
"lastname" -> text
)(Person.apply)(Person.unapply))
implicit val readsPerson: Reads[Person] = (
((__ \ "firstname").read[String]) and
((__ \ "lastname").read[String])
)(Person.apply _)
implicit val writesItem = Writes[Person] {
case Person(firstname, lastname) =>
Json.obj(
"firstname" -> firstname,
"lastname" -> lastname
)
}
}
现在这在浏览器中运行得非常好。
然而,当我尝试从 curl 调用操作时
curl -H "Content-Type: application/x-www-form-urlencoded" -X POST -d '{"firstname":"abhishek", "lastname":"srivastava"}' http://localhost:9000/
失败并显示冗长的 HTML 消息。
我的理解是,如果我使用 x-www-form-urlencoded,那么在 post 时,我可以接受来自 HTML 表单和 JSON请求。
我做错了什么吗?还是我的理解有问题?
基本上我想要相同的控制器方法 Action 来服务 json post 请求以及 html 表单提交。
简短回答:在客户端设置 Content-Type
header,在服务器端使用默认的 body 解析器,这一切都会像魔术一样工作! :) 将 Action(parse.urlFormEncoded)
替换为简单的 Action
,然后将使用默认解析器。
长答案:
默认解析器将根据 Content-Type
header 自动使用正确的解析器,无论是 application/x-www-form-urlencoded
、application/json
还是其他。
然后在您的 post
方法中,bindFromRequest
将检查所有物体以确定已设置的物体,无论是 asFormUrlEncoded
还是 asJson
,然后将其用于表单数据处理。