1

I am not much familier with spray json, but I have to convert the below json into Array[myTest]

Below is the code, but it doesnt work. It throws the following errors: How do I fix them?

Error:(19, 54) Cannot find JsonReader or JsonFormat type class for Array[A$A61.this.myTest]
lazy val converted= trainingDataRef.toJson.convertTo[Array[myTest]]
                                                    ^
Error:(19, 54) not enough arguments for method convertTo: (implicit evidence$1: spray.json.JsonReader[Array[A$A61.this.myTest]])Array[A$A61.this.myTest].
Unspecified value parameter evidence$1.
lazy val converted= trainingDataRef.toJson.convertTo[Array[myTest]]
                                                    ^
Error:(10, 61) could not find implicit value for evidence parameter of type spray.json.DefaultJsonProtocol.JF[Map[String,Any]]
  implicit val format: RootJsonFormat[myTest] = jsonFormat3(myTest.apply)


                                          ^


   Code:                           ^
import spray.json.DefaultJsonProtocol._
import spray.json._

case class myTest (
                        id: String,
                        classDetails: Map[String, Any],
                        school: Map[String, Any])
object myTest {
  implicit val format: RootJsonFormat[myTest] = jsonFormat3(myTest.apply)
}


val trainingDataRef = """[{"id":"my-id","classDetails":{"sec":"2","teacher":"John"},"school":{"name":"newschool"}}]"""

println(trainingDataRef.getClass)


val converted= trainingDataRef.toJson.convertTo[Array[myTest]]
println(converted)
2
  • Those Map[String, Any] are troublesome Commented Nov 28, 2017 at 16:00
  • ok, that can be changed , what would be the feasible way? Instead of Map[String, Any], should I use JsonNode? Commented Nov 28, 2017 at 16:05

1 Answer 1

1

spray-json has good documentation, try take a look there. Basically, you have to define your case classes and implement JsonFormat for them:

import spray.json.DefaultJsonProtocol._
import spray.json._

case class ClassDetails(sec: String, teacher: String)
object ClassDetails {
  implicit val format: RootJsonFormat[ClassDetails] = jsonFormat2(ClassDetails.apply)
}

case class School(name: String)
object School {
  implicit val format: RootJsonFormat[School] = jsonFormat1(School.apply)
}

case class ClassInfo
(
  id: String,
  classDetails: ClassDetails,
  school: School
)

object ClassInfo {
  implicit object ClassInfoFormat extends RootJsonFormat[ClassInfo] {
    def write(c: ClassInfo): JsValue = JsObject(
      "id" -> JsString(c.id),
      "classDetails" -> c.classDetails.toJson,
      "school" -> c.school.toJson
    )
    def read(value: JsValue): ClassInfo = {
      value.asJsObject.getFields("id", "classDetails", "school") match {
        case Seq(JsString(name), details, school) =>
          new ClassInfo(name, details.convertTo[ClassDetails], school.convertTo[School])
        case _ => throw new DeserializationException("ClassInfo expected")
      }
    }
  }
}

val json = """[{"id":"my-id","classDetails":{"sec":"2","teacher":"John"},"school":{"name":"newschool"}}]"""
// JSON string to case classes
val classInfos = json.parseJson.convertTo[Seq[ClassInfo]]
classInfos.zipWithIndex.foreach { case (c, idx) =>
  println(s"$idx => $c")
}
println
// Seq[ClassInfo] to JSON
println(s"$classInfos: ")
println(classInfos.toJson.prettyPrint)
Sign up to request clarification or add additional context in comments.

6 Comments

Thank you very much, its help ful . But why in my case I'm getting some additional fields and values appended to the json EX:
[ { "id": "my-id", "classDetails": { "fields": { "sec": { "value": "2" }, "teacher": { "value": "John" } } }, "school": { "fields": { "name": { "value": "newschool" } } } } ]
Have you changed something? Because I don't see any additional fields. Here is my output: pastebin.com/1NwK2Vak. I'm using spray-json 1.3.3
I have to send this to another caller, there the json is changed as above.In that application, they receive the json and copy it to another case class using as[] , but that case class is similar to the above. I don't have control on that, I should only send proper input
btw, I have changed the case class as shown below:case class ClassInfo ( id: String, classDetails: JsValue, school: JsValue )
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.