12

First, I searched a lot on Google and StackOverflow for questions like that, but I didn't find any useful answers (to my big surprise).

I saw something about Play Framework, how to create JSON array in Java and how to create JSON objects in Java, but I don't want to use Play Framework and I don't know if the creation of JSON objects differ from Scala to Java.

Following is the JSON I want to create. Later I'll convert the object into a string to send it via a POST request (through an API call).

{
    "start_relative": {
        "value": "5",
        "unit": "years"
    },
    "metrics": [
        {
        "name": "DP_391366" # S-Temperature - Celsius
        },
        {
            "name": "DP_812682" # Sensor-A4 Luminosity
        }
    ]
}

How can I do something like that in Scala?

soodankit
  • 81
  • 8
Paladini
  • 4,522
  • 15
  • 53
  • 96
  • It's unclear what you're asking. Are you trying to go from a Scala class to a JSON string? Can you post the scala class/pobject you are trying to convert? – djechlin Oct 23 '15 at 17:49
  • No, I don't want to convert a Scala class to JSON string. I want to create a valid JSON from Scala. – Paladini Oct 23 '15 at 17:53
  • What does "from Scala" mean? – djechlin Oct 23 '15 at 17:57
  • I just need to create a valid JSON string using Scala as programming language. Later I'll use this valid JSON string to send it via POST request to an API. – Paladini Oct 23 '15 at 18:00
  • 1
    @FernandoPaladini What you are talking about is called serialization and it involves taking a data structure (an object) and turning it into a JSON string programmatically. You can do it manually but it's much, much easier to use an existing library which will do it faster than you. – 2rs2ts Oct 23 '15 at 18:05
  • 2
    An overview of Scala json libraries : http://stackoverflow.com/questions/8054018/what-json-library-to-use-in-scala/14442630#14442630 – Peter Neyens Oct 23 '15 at 18:09
  • @2rs2ts Thanks for the comment! In my case I don't take a data structure (as you said, an object) and turn it into a JSON. Actually the JSON isn't related to my code or my classes, I'm creating the JSON because I need it to call an API, so I'm hardcoding the JSON string (but I want a easier way to do that using Scala libraries (like Java's json-simple), I take to much time to hardcode JSON in a string). – Paladini Oct 23 '15 at 18:17

2 Answers2

14

You should use a library that handles serialization/deserialization. I would consider choosing between Spray Json and Play Json.

I will explain to you how the process works with Play first, and it's very similar to that in Spray.

Let's say you have a class, and an object with an instance and a json as string:

case class MyClass(id: Int,
                   name: String,
                   description: String)

object Data {
  val obj: MyClass = MyClass(1, "me", "awesome")
  val str: String =
      """
        |{
        | "id": 1,
        | "name": "me",
        | "description": "awesome"
        |}
      """.stripMargin
}

For MyClass to be serialized/deserialized, you will need an implicit formatter, specific for this, so you will create an object that contains this formatter using Play.

trait MyClassPlayProtocol {
  implicit val formatAbility = Json.format[Ability]
}
object MyClassPlayProtocol extends MyClassPlayProtocol

The serialization/deserialization will look something like this:

object PlayData {

  import play.api.libs.json.JsValue
  import play.api.libs.json.Json
  import MyClassPlayProtocol._
  import General._

  val str2Json: JsValue = Json.parse(str)
  val obj2Json: JsValue = Json.toJson(obj)

  val json2Str: String = Json.stringify(str2Json)
  val json2Obj: MyClass = obj2Json.as[MyClass]
}

In Spray, the protocol will look like this:

trait MyClassSprayProtocol extends DefaultJsonProtocol {
  implicit val myClassFormat = jsonFormat3(MyClass)
}
object MyClassSprayProtocol extends MyClassSprayProtocol

and the serialization/deserialization:

object SprayData {

  import spray.json._
  import MyClassSprayProtocol._
  import General._

  val str2Json: JsValue = str.parseJson
  val obj2Json: JsValue = obj.toJson

  val json2Str: String = str2Json.compactPrint
  val json2Obj: MyClass = obj2Json.convertTo[MyClass]
}

As you can see, it's mostly a matter of choice between this two. Both are still improved and probably will be in the near future.

Depending on the benchmark, you will find that one is better than the other by a few miliseconds (usually Spray).

I for one am using Spray at work and Play in some personal projects, and I can't say I found something fundamentally different from one to another.

EDIT:

And to finally answer your question, to go from MyClass to String (serialization), you will do something like this:

PLAY:  Json.stringify(Json.toJson(myClass))
SPRAY: myClass.toJson.compactPrint

And the deserialization:

PLAY:  Json.parse(string).as[MyClass]
SPRAY: myClass.parseJson.convertTo[MyClass]
tasegula
  • 889
  • 1
  • 12
  • 26
3

You need to use a library if you dont want it to do by yourself there are serveral:

Note: The cool Java Gson LIbrary looses a lot of Magic if you want to use it with Scala, because they dont know Collections. So if you want to use this library you have to convert the "Scala List" to java.util.List and after that use Gson.

Kordi
  • 2,405
  • 1
  • 14
  • 13
  • 1
    You can also use Jackson with the [Scala module](https://github.com/FasterXML/jackson-module-scala). – 2rs2ts Oct 23 '15 at 18:04