EzDevInfo.com

json4s

A single AST to be used by other scala json libraries Json4s by json4s

Which JSON library to use when storing case objects?

I need to serialize akka events to json. Based on "What JSON library to use in Scala?" I tried several libraries. Since my serializer should know nothing of all my concrete events, the events consisting of case classes and case objects should be serialised using reflection. json4s seems to match my requirements best.

class Json4sEventAdapter(system: ExtendedActorSystem) extends EventAdapter {
  implicit val formats = Serialization.formats(FullTypeHints(List(classOf[Evt])))
  override def toJournal(event: Any): Any = event match {
case e: AnyRef =>
  write(e).getBytes(Charsets.UTF_8)}

override def fromJournal(event: Any, manifest: String): EventSeq = event match {
case e: Array[Byte] => {
      EventSeq.single(read[Evt](new String(e.map(_.toChar))))}}

The problem using json4s is, that no matter which implementation is used Deserialization of objects produces different instances. Since we heavily use pattern matching for the case object this breaks all our existing code.

So my question is: which JSON library could be used with scala and akka persistence when storing case objects?

Is there even one library that handles deserialization of case objects via reflection correctly? - or does anyone have a good workaround?


Source: (StackOverflow)

Is it possible to serialize non case classes in Scala?

Is it possible to serialize object of below class using Json4s or lift or any other library?

class User(uId: Int) extends Serializable {
  var id: Int = uId
  var active: Boolean = false
  var numTweets: Int = 0
  var followers: ArrayBuffer[Int] = null
  var following: ArrayBuffer[Int] = null
  var userTimeline: Queue[String] = null
  var homeTimeline: Queue[String] = null
  var userTimelineSize: Int = 0
  var homeTimelineSize: Int = 0
  //var notifications: Queue[String] = null
  var mentions: Queue[String] = null
  var directMessages: Queue[String] = null
}

Source: (StackOverflow)

Advertisements

How do you create Json object with values of different types?

How do you create Json object with values of different types ?

I'm using spray-json

Here is the code

val images : List[JsObject] = fetchImageUrls(url).map((url: String) => {
  JsObject(List(
        "link_path" -> JsString(url),
        "display_name" -> JsString("image"),
        "size" -> JsString(""),
        "modified" -> JsString(""),
        "thumbnail" -> JsString(url),
        "filename" -> JsString("image"),
        "is_dir" -> JsBoolean(x = false),
        "thumb_exists" -> JsBoolean(x = true)) )
  })

val jsonAst: JsObject = JsObject(List(
  "client" -> JsString("urlimages"),
  "view" -> JsString("thumbnails"),
  "contents" -> JsArray(images)
))

It works but looks really heavy. Is there a way to define json with code like this ?

val images : List[List[(String, Any)]] = fetchImageUrls(url).map((url: String) => {
  List(
    "link_path" -> url,
    "display_name" -> "image",
    "size" -> "",
    "modified" -> "",
    "thumbnail" -> url,
    "filename" -> "image",
    "is_dir" -> false,
    "thumb_exists" -> true)
})

val jsonAst = List(
  "client" -> "urlimages",
  "view" -> "thumbnails",
  "contents" -> images
).toJson

It doesn't work saying that

Cannot find JsonWriter or JsonFormat type class for List[(String, Object)]
    ).toJson
      ^

Which I get, type of each field is not defined at compile time. But why wouldn't it work if serializer does pattern matching anyway ?

Thanks!


Source: (StackOverflow)

How to parse and extract information from json array using json4s

I am currently trying to extract the information from a json array using json4s (scala).

An example data is as follows:

val json = """
  [
    {"name": "Foo", "emails": ["Foo@gmail.com", "foo2@gmail.com"]},
    {"name": "Bar", "emails": ["Bar@gmail.com", "bar@gmail.com"]}
  ]
"""

And my code is as follows:

case class User(name: String, emails: List[String])
case class UserList(users: List[User]) {
  override def toString(): String = {
    this.users.foldLeft("")((a, b) => a + b.toString)
  }
}

val obj = parse(json).extract[UserList]
printf("type: %s\n", obj.getClass)
printf("users: %s\n", obj.users.toString)

The output turns out to be:

type: class UserList
users: List()

It seems that the data is not correctly retrieved. Is there any problem with my code?

UPDATE: It works according to the suggestion of @Kulu Limpa.


Source: (StackOverflow)

@JsonIgnore serialising Scala case class property using Jackon and Json4s

I'm trying to prevent one of the properties of a Scala case class being serialised. I've tried annotating the property in question with the usual @JsonIgnore and I've also tried attaching the @JsonIgnoreProperties(Array("property_name")) to the case class. Neither of which seem to achieve what I want.

Here's a small example:

import org.json4s._
import org.json4s.jackson._
import org.json4s.jackson.Serialization
import org.json4s.jackson.Serialization.{read, write}
import com.fasterxml.jackson.annotation._

object Example extends App {

    @JsonIgnoreProperties(Array("b"))
    case class Message(a: String, @JsonIgnore b: String)

    implicit val formats = Serialization.formats(NoTypeHints)
    val jsonInput = """{ "a": "Hello", "b":"World!" }"""
    val message = read[Message](jsonInput)
    println("Read " + message) // "Read Message(Hello,World!)

    val output = write(message) 
    println("Wrote " + output) // "Wrote {"a":"Hello","b":"World!"}"
}

Source: (StackOverflow)

Why does json4s need a Scala compiler as a runtime dependency

I've discovered that by using json4s native

    <dependency>
        <groupId>org.json4s</groupId>
        <artifactId>json4s-native_2.10</artifactId>
        <version>3.2.9</version>
    </dependency>

brings scalap and scala-compiler dependencies.

Why does it need it?

Does it generate code on the fly at runtime?

Why doesn't it use macros that do this processing at compile time?


Source: (StackOverflow)

Producing json in a Scala app using json4s

I am attempting to produce JSON in a Scala app using json4s. Fairly straight forward, Here's some sample value I put together to test it in my Scalatra app:

import org.json4s._
import org.json4s.JsonDSL._


object JsonStub {
    val getPeople = 
        ("people" ->
            ("person_id" -> 5) ~
            ("test_count" -> 5))

}

In my controller, I simply have:

import org.json4s._
import org.json4s.JsonDSL._
import org.json4s.{DefaultFormats, Formats}

class FooController(mongoDb: MongoClient)(implicit val swagger: Swagger) extends ApiStack with NativeJsonSupport with SwaggerSupport {

get ("/people", operation(getPeople)) {
        JsonStub.getPeople
    }   

}

The output I'm seeing in the browser however, is the following:

{
  "_1": "people",
  "_2": {
    "person_id": 5,
    "test_count": 5
  }
}

Any clue where the _1 and _2 keys are coming from? I was expecting this output instead:

{
  "people":{
    "person_id": 5,
    "test_count": 5
  }
}

Source: (StackOverflow)

Importing .jar files into Scala environment

Even after reading: Scala, problem with a jar file, I'm still a bit confused. I am trying to import some packages into my Scala file, and the interpreter is not recognizing them even after adding to classpath.

One example:

I have the import statement:

import org.json4s._

I downloaded the .jar from here: http://mvnrepository.com/artifact/org.json4s/json4s-native_2.10/3.2.4

and added to the interpreter classpath using:

scala> :cp /Users/aspangher13/Downloads/json4s-native_2.10-3.2.4.jar

Scala acknowledges the classpath:

Your new classpath is: ".:/Users/aspangher13/Downloads/json4s-native_2.10-3.2.4.jar:/Users/aspangher13/Downloads/jna-3.5.2.jar"

But still throws this error:

<console>:7: error: object scalatra is not a member of package org
   import org.json4s._

Can anyone see what I'm doing wrong? Thanks!!

And as a followup, does anyone know where to find the package: JsonAST._?


Source: (StackOverflow)

Purpose of `render` in json4s

In json4s examples and documentation I often see the idioms

compact(render(jval))

and

pretty(render(jval))

I do not think I have actually seen an example with compact or pretty applied directly to a code generated JValue, but it is not clear to me what render is doing here. Render has type JValue => JValue and I do not see any obvious difference it makes and running

json.take(100000).filter(x => compact(render(x)) != compact(x))

on some of my data returns an empty an empty collection.

What does render actually do?


Source: (StackOverflow)

How to serialize object to AST using json4s?

I am writing a Customer Serializer. In that Serializer I would like to somehow say: "and this thing you already know how to serialize".

My current approach looks like that:

    import org.json4s.native.Serialization._
    import org.json4s.JsonDSL.WithBigDecimal._

    object WindowSerializer extends CustomSerializer[Window](format =>
      ( [omitted],
        {
          case Window(frame, size) =>

            ( "size" -> size ) ~
            ( "frame" -> parse(write(frame)) )
        }))

That parse(write(frame)) things is both ugly and inefficient. How to fix that?


Source: (StackOverflow)

Generating Json string using Json4S from a list containing Some and None values

I am using Scalatra, which in turn uses Json4S to generate Json string. I receive

["A","B"]

for

List(Some("A"),None,Some("B"))

I would like to receive

["A",undefined,"B"]

How can this be fixed ?


Source: (StackOverflow)

Json4s custom serializer with unordered fields

In the example given on the json4s readme https://github.com/json4s/json4s#serializing-non-supported-types the match only works if the fields are order {"start":0,"end":0}. If the start and end fields are swapped then the match doesn't work. Is there anyway to write the below case match such that the JSON field ordering doesn't matter?

case JObject(JField("start", JInt(s)) :: JField("end", JInt(e)) :: Nil)

Source: (StackOverflow)

Is it possible to make json4s not to throw exception when required field is missing?

Is it possible to make json4s not to throw exception when required field is missing ?

When I "extract" object from raw json string it throws exception like this one

org.json4s.package$MappingException: No usable value for pager
No usable value for rpp
Did not find value which can be converted into byte
    at org.json4s.reflect.package$.fail(package.scala:98)
    at org.json4s.Extraction$ClassInstanceBuilder.org$json4s$Extraction$ClassInstanceBuilder$$buildCtorArg(Extraction.scala:388)
    at org.json4s.Extraction$ClassInstanceBuilder$$anonfun$11.apply(Extraction.scala:396)

Is it possible just to let it be null ?


Source: (StackOverflow)

How to Manipulate JSON AST in Scala

I am experimenting with the json4s library (based on lift-json). One of the things I would like to do is to parse a JSON string into an AST, and then manipulate it.

For example, I would like to upsert a field (insert the field into the AST if it does not exist, or update its value if it does).

I have not been able to find how to do it in the documentation. Experimenting with the available methods, I have come up with the following, which works, but feels clumsy.

import org.json4s._
import org.json4s.JsonDSL._
import org.json4s.native.JsonMethods._

object TestJson {
  implicit val formats = DefaultFormats

  def main(args: Array[String]): Unit = {
    val json = """{"foo":1, "bar":{"foo":2}}"""
    val ast = parse(json).asInstanceOf[JObject]

    println( upsertField(ast, ("foo" -> "3")) )
    println( upsertField(ast, ("foobar" -> "3")) )
  }

  def upsertField(src:JObject, fld:JField): JValue = {
    if(src \ fld._1 == JNothing){
      src ~ fld
    }
    else{
      src.replace(List(fld._1), fld._2)
    }
  }
}

I dislike it for many reasons:

  1. Having to explicitly cast the results of parse(json) to JObject
  2. The result of the upsertField function is a JValue, which I will have to recast if I want to manipulate the object further
  3. The upsertField function just feels very unelegant
  4. It does not work for fields that are not at the top level of the hierarchy

Is there a better way to transform the AST?

EDIT: as a workaround to the problem, I have managed to convert my JSON to Scala regular classes, and manipulate them with lenses (Using Lenses on Scala Regular Classes)


Source: (StackOverflow)

What `JObject(rec) <- someJArray` means inside for-comprehension

I'm learning Json4s library.

I have a json fragment like this:

{
    "records":[
        {
            "name":"John Derp",
            "address":"Jem Street 21"
        },
        {
            "name":"Scala Jo",
            "address":"in my sweet dream"
        }
    ]
}

And, I have Scala code, which converts a json string into a List of Maps, like this:

import org.json4s._
import org.json4s.JsonAST._
import org.json4s.native.JsonParser

  val json = JsonParser.parse( """{"records":[{"name":"John Derp","address":"Jem Street 21"},{"name":"Scala Jo","address":"in my sweet dream"}]}""")

  val records: List[Map[String, Any]] = for {
    JObject(rec) <- json \ "records"
    JField("name", JString(name)) <- rec
    JField("address", JString(address)) <- rec
  } yield Map("name" -> name, "address" -> address)

  println(records)

The output of records to screen gives this:

List(Map(name -> John Derp, address -> Jem Street 21), Map(name -> Scala Jo, address -> in my sweet dream))

I want to understand what the lines inside the for loop mean. For example, what is the meaning of this line:

JObject(rec) <- json \ "records"

I understand that the json \ "records" produces a JArray object, but why is it fetched as JObject(rec) at left of <-? What is the meaning of the JObject(rec) syntax? Where does the rec variable come from? Does JObject(rec) mean instantiating a new JObject class from rec input?

BTW, I have a Java programming background, so it would also be helpful if you can show me the Java equivalent code for the loop above.


Source: (StackOverflow)