玩框架。在相同的操作

时间:2015-06-24 22:45:40

标签: scala playframework typesafe-activator

我使用Play Scala框架编写了此示例应用程序。 (TypeSafe Activator)

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,那么在发布时,我可以接受来自HTML表单和JSON请求的请求。

我做错了吗?还是我的理解有缺陷?

基本上我想要相同的控制器方法Action来服务json post请求以及html表单提交。

1 个答案:

答案 0 :(得分:4)

简短回答:在客户端设置Content-Type标题,在服务器端使用默认的主体解析器,它就像魔法一样工作! :)用Action(parse.urlFormEncoded)替换Action,然后使用默认解析器。

答案很长:

默认解析器将根据Content-Type标头自动使用正确的解析器,无论是application/x-www-form-urlencodedapplication/json还是其他解析器。

然后在post方法中,bindFromRequest将检查所有正在确定哪一个已设置的正文,无论是asFormUrlEncoded还是asJson,然后将其用于表单数据处理