scalajson4sscalatra

json4s used in scalatra application throws "com.fasterxml.jackson.databind.JsonMappingException: No content to map due to end-of-input"


json4s used in scalatra application throws "com.fasterxml.jackson.databind.JsonMappingException: No content to map due to end-of-input" when a POST request through a browser.

I have a ScalatraServlet to serve FORM submit from browser. Here is the Servlet.

class PagesController(service: RecordService) extends ScalatraServlet with JacksonJsonSupport  {

  post("/addRecord") {
    contentType = "text/html"
    //implicit val formats = DefaultFormats
    val jsonPayload = request.body
    println(s"payload: $jsonPayload")
    val x = parse(request.body)
    println(s"parsed: $x")
    val record = x.extract[MRecord]
    println(s"object: $record")
    service.add(Record(0, "Mocked data"))
    println(s"added $recordModel")
    redirect(URL.LANDING_PAGE_URL)
  }

When I run the POST request through cli/rest-client with content-type as appplication/www-form-url-encode, there is no such error and I can confirm from the println statements. However, when a browser submits a form, "com.fasterxml.jackson.databind.JsonMappingException: No content to map due to end-of-input"

What is the cause of this exception to occur only when the form is submitted and not when submitted through REST client/cli?


Solution

  • Looks like your code expects that a request body is JSON but a browser form submits param_name1=param_value1&param_name2=param_value2 as a request body. If you have a field named json that contains JSON in your form, probably, you can get a JSON as follows:

    post("/addRecord") {
      val jsonPayload = params("json")
      val x = parse(jsonPayload)
      ...
    }
    

    By the way, the json4s version that is used in Scalatra 2.7.0 is 3.6.7. It would be better to upgrade to this version: https://github.com/scalatra/scalatra/blob/v2.7.0/project/Dependencies.scala#L55