JsonParseException: Unexpected character (':&#

2019-08-18 02:02发布

问题:

While trying to learn JSON-parsing in Scala using Play Framework's ScalaJson through JSON automated mapping using case classes, I'm getting the said error.

com.fasterxml.jackson.core.JsonParseException: Unexpected character (':' (code 58)): expected a valid value (number, String, array, object, 'true', 'false' or 'null')
 at [Source: 
"column" : {
    "name" : "column_name"
}; line: 2, column: 11]
    at com.fasterxml.jackson.core.JsonParser._constructError(scalaPlayJson.sc:1577)
    at com.fasterxml.jackson.core.base.ParserMinimalBase._reportError(scalaPlayJson.sc:529)
    at com.fasterxml.jackson.core.base.ParserMinimalBase._reportUnexpectedChar(scalaPlayJson.sc:458)
    at com.fasterxml.jackson.core.json.ReaderBasedJsonParser._handleOddValue(scalaPlayJson.sc:1620)
    at com.fasterxml.jackson.core.json.ReaderBasedJsonParser.nextToken(scalaPlayJson.sc:685)
    at play.api.libs.json.jackson.JsValueDeserializer.deserialize(scalaPlayJson.sc:175)
    at play.api.libs.json.jackson.JsValueDeserializer.deserialize(scalaPlayJson.sc:124)
    at play.api.libs.json.jackson.JsValueDeserializer.deserialize(scalaPlayJson.sc:119)
    at com.fasterxml.jackson.databind.ObjectMapper._readValue(scalaPlayJson.sc:3704)
    at com.fasterxml.jackson.databind.ObjectMapper.readValue(scalaPlayJson.sc:2001)
    at play.api.libs.json.jackson.JacksonJson$.parseJsValue(scalaPlayJson.sc:231)
    at play.api.libs.json.StaticBinding$.parseJsValue(scalaPlayJson.sc:12)
    at play.api.libs.json.Json$.parse(scalaPlayJson.sc:167)
    at #worksheet#.#worksheet#(scalaPlayJson.sc:50)

The input in question is the simplest JSON one could think of [file: column.json]

{
  "column": {
    "name": "column_name"
  }
}

I'm using the following code to parse the given Json file.

case class Column(
                   tableId:      Option[Int]     = None,
                   id:           Option[Int]     = None,
                   name:         String,
                   shouldCopy:   Option[Boolean] = None,
                   dataType:     Option[String]  = None,
                   defaultValue: Option[String]  = None
                 ) {
  def showColumnInfo: Unit = println(s"Name = $name")
}

object Column {
  implicit val reads = Json.reads[Column]
  implicit val writes = Json.writes[Column]
  implicit val format = Json.format[Column]
}

Json.parse(Source.fromFile(s"$path/column.json").mkString("")).
  asOpt[Column].
  getOrElse(Column(name = "Could not read")).
  showColumnInfo

Things that I've tried without success:

  • Change the key "column" to "Column" in JSON (capitalize 'C' to match case class's name)
  • Provide the above JSON as String instead of reading it from file

My questions are:

  • What's causing the error?
  • Where can I find list of all JsonParseException error codes with their meanings?

Framework versions:

  • Scala v2.11.11
  • Play-Json v2.6.6 [SBT: "com.typesafe.play" %% "play-json" % "2.6.6"]
  • SBT v1.0.3

回答1:

Turns out my input JSON was wrong (it was a valid JSON, but incorrect as per provided case class). I had wrapped it inside an extra pair of braces {} where it should have been

{
  "name": "column_name"
}

For anyone starting with Play-JSON, I would suggest them to use JsValue.as[T] instead of JsValue.asOpt[T] because the latter doesn't report any errors and you'll keep banging your head (I wasted over 5 hours :-(). The docs warn about it in advance:

Although the asOpt method is safer, any error information is lost.