Removing Json array deserialization into a Scala object

I'm having serious problems deserializing the JSON array for a Scala object

[{"name":"Cool","city":"College Park","address":"806","id":1},{"name":"Mars ","city":"Durham","address":"12","id":2},{"name":"Something","city":"Raleigh ","address":"","id":3},{"name":"test","city":"","address":"","id":5}] 

I tried gson, jerkson (jackson Scala wrapper), sjson, flexjson. None of them worked. I have a list of clients. List [Client].

This is the closest I have:

 val array = new JsonParser().parse( customers ).getAsJsonArray() 

This gave me 4 arrays. However, this obviously did not give me the client object. I tried Jerkson.

 val array = parse[List[Customer]](customers) 

But I understand that.

 GenericSignatureFormatError occured : null 

I'm just trying to find an easy way, like in Java.

Here is my Scala class.

  case class Customer( id : Pk[ Int ], name : String, address : Option[ String ], city : Option[ String ], state : Option[ String ], user_id : Int ) object Customer extends Magic[ Customer ]( Option( "Customer" ) ) { def apply( name : String, address : String, city : String, state : String, user_id : Int ) = { new Customer( NotAssigned, name, Some( address ), Some( city ), Some( state ), user_id ) } def delete( id : Int ) = { SQL( "DELETE from Customer where id = {id}" ).onParams( id ).executeUpdate() } } 

Thanks for any help.

+4
source share
7 answers

With gson, you can write your own json reader:

 case class Customer(id: Int, name: String, address: Option[String], city: Option[String], state: Option[String], user_id: Int) object CustomerJsonReader { def read(in: Reader) = readCustomers(new JsonReader(in)) def readCustomers(reader: JsonReader) = { val customers = new ListBuffer[Customer] reader.beginArray() while (reader.hasNext()) { customers += readCustomer(reader) } reader.endArray() customers toList } def readCustomer(reader: JsonReader): Customer = { var id = 0 var customerName = "" var address: Option[String] = None var city: Option[String] = None var state: Option[String] = None var userId = 0 reader.beginObject() while (reader.hasNext()) { val name = reader.nextName() name match { case "id" => id = reader.nextInt() case "address" => address = Some(reader.nextString()) case "state" => state = Some(reader.nextString()) case "user_id" => userId = reader.nextInt() case "name" => customerName = reader.nextString() case "city" => city = Some(reader.nextString()) case _ => reader.skipValue() } } reader.endObject() Customer(id, customerName, address, city, state, userId) } } val json = """ [{"name":"Cool","city":"College Park","address":"806","id":1}, {"name":"Mars ","city":"Durham","address":"12","id":2}, {"name":"Something","city":"Raleigh ","address":"","id":3}, {"name":"test","city":"","address":"","id":5}] """ val customers: List[Customer] = CustomerJsonReader.read(new StringReader(json)) 
+4
source

I know that with gson you will need Array instead of scala.List. I would suggest doing this. You should use this with gson.fromJson, I think.

+3
source

You can also try Jerksson = Jackson + Scala
Easy to use, even if I had problems with special JSON fields containing "-"
A small tattoo that I recently saw on twitter: http://logician.free.fr/index.php/2011/09/16/play-scala-and-json/

+3
source

I was embarrassed right now, and I tried trying GSON, Lift-Json, Sjson, and finally Jerkson , and found peace with this.

Here's how I use it in combination with Play:

http://logician.eu/index.php/2011/09/16/play-scala-and-json/

http://logician.eu/index.php/2011/11/01/writing-custom-deserializers-for-jerkson/

+2
source

I use the Lift json library for this purpose, it easily allows you to parse JSON and retrieve values ​​in case classes. It is packaged as a separate can, so you do not need the entire frame of the elevator to use it.

 import net.liftweb.json._ import net.liftweb.json.JsonDSL._ implicit val formats = DefaultFormats val json: String = "[{...." val parsed: JValue = parse(json) val customers: List[Customer] = parsed.extract[List[Customer]] 

Just make sure that additional fields are defined in the case field using the option. I noticed that in your code the objects do not have the user_id field, which will lead to a parsing error if the user_id field is declared as Int instead of Option[Int] .

+1
source

In addition to trying to make Jerkson (which is a great library to use from what I heard), you can also try the Jackson Scala module - modules are the official Jackson distribution method for working with third-party data types, as well as native data types and constructs of other languages JVM. (this does not mean that it is more official than Jerksson, just there are many useful Jackson extension modules that many developers are not familiar with)

Problems with the Scala module are discussed on Jackson's main mailing lists ( user@jackson.codehaus.org ); you may have found a boundary case that could be fixed.

+1
source

I wrote a dsl parser / validator that allows you to explicitly solve the erase problem of any type. Out of the box, it processes the classes classes, tuples, Option, Either, list, map, joda DatetTime, switching to functions, multiple key matching and reassigning key names.

He uses Jackson's parson

https://github.com/HigherState/jameson

0
source

Source: https://habr.com/ru/post/1379134/


All Articles