Extract String value using json4s
Asked Answered
J

1

33

I have following Scala console session for json4s, where I am trying to extract String value from a parsed json:

scala> import org.json4s._
import org.json4s._

scala> import org.json4s.native.JsonMethods._
import org.json4s.native.JsonMethods._

scala> val s = """ {"a": "hello"} """
s: String = " {"a": "hello"} "

scala> val json = parse(s)
json: org.json4s.JValue = JObject(List((a,JString(hello))))

scala> json \ "a"
res0: org.json4s.JValue = JString(hello)

scala> res0.extract[String]
<console>:17: error: No org.json4s.Formats found. Try to bring an instance of org.json4s.Formats in scope or use the org.json4s.DefaultFormats.
              res0.extract[String]
                          ^

scala> import org.json4s.Formats._
import org.json4s.Formats._

scala> res0.extract[String]
<console>:20: error: No org.json4s.Formats found. Try to bring an instance of org.json4s.Formats in scope or use the org.json4s.DefaultFormats.
              res0.extract[String]
                          ^

scala> import org.json4s.DefaultFormats._
import org.json4s.DefaultFormats._

scala> res0.extract[String]
<console>:23: error: No org.json4s.Formats found. Try to bring an instance of org.json4s.Formats in scope or use the org.json4s.DefaultFormats.
              res0.extract[String]
                          ^

org.json4s.DefaultFormats, org.json4s.Formats and there members are already in scope. How can I fix this?

EDIT1

From @mfirry 's answer, this works:

scala> implicit val formats = DefaultFormats
formats: org.json4s.DefaultFormats.type = org.json4s.DefaultFormats$@12b195f5

scala> val json = parse(""" {"a": "hello", "b": 1.2} """)
json: org.json4s.JValue = JObject(List((a,JString(hello)), (b,JDouble(1.2))))

scala> (json \ "b").extract[String]
res6: String = 1.2

scala> (json \ "b").extract[Double]
res7: Double = 1.2
Jankowski answered 3/9, 2015 at 14:28 Comment(2)
extractOpt returns Option of specified type, if the field is an optional one.Fasciate
BEWARE: Json4s is vulnerable under DoS/DoW attacks!Bobseine
A
74

You just need to add

implicit val formats = DefaultFormats

and it'll work just ok.

Anikaanil answered 3/9, 2015 at 14:46 Comment(7)
why this is required??Cycle
And if you need this in a class, you can just declare it at the top of the classSyrian
Even if you just need it in a function, declare it at the top better than above. It will prevent for further java.io.NotSerializableExceptionHydrogen
I second @Nilesh. What makes this work and why is it necessary?Byran
So a few methods from json4s api (namely render) require an implicit Formats parameter. Formats contain stuff like date formatting rules and other settings. So Json4s gives you a default you can use. By adding that line you'll have it in scope. Have look for more details: github.com/json4s/json4s/blob/3.6/core/src/main/scala/org/…Anikaanil
@Anikaanil How do we know for the methods that they need something to be imported implicitly. Can you please point out some syntactic hint?Uniaxial
For example If you look at json4s source code you'll see ` def extract[A](implicit formats: Formats, mf: scala.reflect.Manifest[A]): A = `Anikaanil

© 2022 - 2024 — McMap. All rights reserved.