Check alle échte Black Friday-deals Ook zo moe van nepaanbiedingen? Wij laten alleen échte deals zien

[Scala] De eenvoudigste manier om met Json te werken?

Pagina: 1
Acties:

  • Lethalis
  • Registratie: April 2002
  • Niet online
Sinds kort ben ik aan het spelen met Scala. Over het algemeen vind ik de syntax een stuk duidelijker dan bij Java en C#, maar soms kom je van die dingen tegen dat je denkt "kan dit niet veel eenvoudiger?" :)

Voor Java heeft Google bijvoorbeeld de Gson library gemaakt. Converteren kan dan vrij eenvoudig:

Java:
1
2
3
4
5
6
7
8
Persoon p = new Persoon(1, "Pietje", 33);
Gson gson = new Gson();

// Naar Json 
String json = gson.toJson(p);

// Van Json
Persoon p2 = gson.fromJson(json, Persoon.class);


Ga ik echter met Scala aan de slag, dan wordt vaak aangeraden om de Json library van het Play Framework te gebruiken. Dit leidt tot code als:

Scala:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
// Zodat de Json library personen kan lezen
implicit val persoonReads = new Reads[Persoon] {
    def reads(js: JsValue): JsSuccess[Persoon] = {
        new JsSuccess(new Persoon(
            (js \ "id").as[Int],
            (js \ "naam").as[String],
            (js \ "leeftijd").as[Int]
        ))
    }
}

// Zodat de Json library personen kan schrijven
implicit val persoonWrites = new Writes[Persoon] {
    def writes(p:Persoon) : JsValue = {
        Json.obj(
            "id" -> p.id,
            "naam" -> p.naam,
            "leeftijd" -> p.leeftijd
        )
    }
}

// Naar Json
val p = new Persoon(1, "Pietje", 33)
val js = Json.toJson(p)

// Van Json
val p2 = js.as[Persoon]


Je moet dus met implicit vals readers en writers maken, voordat je ook daadwerkelijk classes van en naar Json kunt vertalen. Althans, dat is wat ik er uit begrijp. Mijn code werkt ook, maar echt blij word ik er niet van ;) Althans, ik vind het wel cool dat ik het aan de praat heb gekregen, maar daar is dan alles mee gezegd :+

Nu lijkt het dus net alsof Java in dit geval handiger is. Dat kan natuurlijk niet! :P

Kortom, wat is de eenvoudigste manier in Scala om een class van en naar Json te vertalen? Zonder dat ik van te voren moet beschrijven hoe dit moet gebeuren?

Er zijn meerdere native Json libraries, maar het is mij niet duidelijk voor welke ik moet kiezen dus.

De spray-json library ziet er bijvoorbeeld al een stuk duidelijker uit ( https://github.com/spray/spray-json ), maar die is ook niet zo eenvoudig als Gson.

Alvast bedankt!

[ Voor 7% gewijzigd door Lethalis op 19-10-2014 10:37 ]

Ask yourself if you are happy and then you cease to be.


  • Herko_ter_Horst
  • Registratie: November 2002
  • Niet online
dan wordt vaak aangeraden om de Json library van het Play Framework te gebruiken
Door wie? Kan best zijn dat die Json library populair is bij gebruikers van Play (want standaard ingebouwd) en dat je hem daarom vaker ziet.

Er is natuurlijk geen enkele reden om een framework tegen je zin te gebruiken omdat iemand dat toevallig adviseert. Heck, je kunt zelfs prima die Gson-library blijven gebruiken vanuit Scala.

Kortom, tenzij er bij het advies ook goede redenen worden gegeven om dat te gebruiken t.o.v. de concurrent, zou ik me daar niet te druk om maken. Als je gewoon een actief ontwikkelde library pakt, dan kan er eigenlijk niet zoveel fout. Json is nou ook weer geen rocket science...

"Any sufficiently advanced technology is indistinguishable from magic."


  • Lethalis
  • Registratie: April 2002
  • Niet online
Herko_ter_Horst schreef op zondag 19 oktober 2014 @ 10:36:
[...]
Json is nou ook weer geen rocket science...
Dat dacht ik ook toen ik er vanochtend aan begon :D

Je hebt gelijk - de library is vooral populair - maar nu nog zoeken naar een goed alternatief. Ik ben iig nu bezig om de spray.io json library te testen. Ik wil niet te snel opgeven en een Java library gebruiken zoals Gson.

Daarnaast begrijp ik niet hoe het kan dat de Play Json library dan zo ingewikkeld is. 1 van de speerpunten is juist dat je met Play snel aan de slag kan en dingen in een mum van tijd kunt ontwikkelen.

Dus ik heb ook het gevoel dat ik simpelweg iets over het hoofd zie ;)

[ Voor 35% gewijzigd door Lethalis op 19-10-2014 11:18 ]

Ask yourself if you are happy and then you cease to be.


  • Creepy
  • Registratie: Juni 2001
  • Laatst online: 23:25

Creepy

Tactical Espionage Splatterer

Jackson heeft een scala module, is dat niet bruikbaar voor je?

"I had a problem, I solved it with regular expressions. Now I have two problems". That's shows a lack of appreciation for regular expressions: "I know have _star_ problems" --Kevlin Henney


  • Lethalis
  • Registratie: April 2002
  • Niet online
Hmm:

http://engineering.ooyala...ring-scala-json-libraries

http://stackoverflow.com/...to-encode-and-decode-json

Blijkbaar geeft het enorme performance voordelen om een compile time parser te specificeren en is dat dus de reden waarom ze het zo doen.

JacksMapper is dus het eenvoudigste te gebruiken denk ik, maar 10x zo traag :D

Update
Ik voel me een beetje dom nu, maar goed. Nadat ik mijn Persoon class heb omgezet naar een case class, kon ik simpelweg de volgende code gebruiken:

Scala:
1
2
3
4
5
6
7
8
9
implicit val persoonReads = Json.reads[Persoon]
implicit val persoonWrites = Json.writes[Persoon]

// Naar Json
val p = new Persoon(1, "Pietje", 33)
val js = Json.toJson(p)

// Van Json
val p2 = js.as[Persoon]


Nu heb ik dus de voordelen van een compile time parser en overzichtelijke code! :)

Mijn Play controller (die weinig boeiends doet) ziet er nu als volgt uit:

Scala:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
package controllers

import play.api._
import play.api.libs.json._
import play.api.libs.functional.syntax._
import play.api.mvc._
import models._

import scala.collection.mutable._

object PersoonController extends Controller {

    val personen = new ListBuffer[Persoon]
    personen += new Persoon(1, "Pietje", 33)
    personen += new Persoon(2, "Jantje", 30)

    implicit val persoonReads = Json.reads[Persoon]
    implicit val persoonWrites = Json.writes[Persoon]

    def getAll() = Action {
        val js = Json.toJson(personen.toList)
        Ok(js)
    }

    def getById(id:Int) = Action {
        val p = personen.filter(p => p.id == id).headOption
        if (p != None)
            Ok(Json.toJson(p))
        else
            NotFound
    }

}


En mijn routes:

code:
1
2
GET     /personen                   controllers.PersoonController.getAll
GET     /personen/:id               controllers.PersoonController.getById(id: Int)


De case class:

Scala:
1
2
3
4
5
6
7
8
package models

case class Persoon(id:Int, naam:String, leeftijd:Int)
{
    override def toString():String = {
        id + " - " + naam + " - " + leeftijd
    }
}


Ik kan nu dus eenvoudig personen opvragen. Finally :D

Volgende stap is dat ik het uit een database haal :)

[ Voor 80% gewijzigd door Lethalis op 19-10-2014 13:30 ]

Ask yourself if you are happy and then you cease to be.


  • Creepy
  • Registratie: Juni 2001
  • Laatst online: 23:25

Creepy

Tactical Espionage Splatterer

Overigens bedoelde ik niet Jacksmapper maar https://github.com/FasterXML/jackson-module-scala, en die is niet zo traag als Jacksmapper, sterker nog, hij is veel sneller dan spray

"I had a problem, I solved it with regular expressions. Now I have two problems". That's shows a lack of appreciation for regular expressions: "I know have _star_ problems" --Kevlin Henney

Pagina: 1