I have written this sample Application using Play Scala framework. (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
      )
  }  
}
Now this works wonderfully from the browser.
However when I try to invoke the action from curl
curl -H "Content-Type: application/x-www-form-urlencoded" -X POST -d '{"firstname":"abhishek", "lastname":"srivastava"}' http://localhost:9000/
It fails with a lengthy HTML message.
My understanding was that if I use x-www-form-urlencoded, then at the time of post, I can accept requests both from the HTML form as well as a JSON request.
Am I doing something wrong? or is my understanding flawed?
Basically I want the same controller method Action to service the json post request as well as the html form submission.
                        
Short answer: set the
Content-Typeheader on the client side, use the default body parser on the server side, and it'll all work just like magic! :) ReplaceAction(parse.urlFormEncoded)with simplyActionwhich'll then use the default parser.Long answer:
The default parser will automatically use the correct parser based on the
Content-Typeheader, whether it'sapplication/x-www-form-urlencoded,application/jsonand some more.Then in your
postmethod,bindFromRequestwill then examine all bodies determining which one has been set, whether it'sasFormUrlEncodedorasJson, then use it for form data handling.