Десериализация массива Json в объект Scala - PullRequest
4 голосов
/ 01 ноября 2011

У меня были серьезные проблемы с попыткой десериализации массива JSON в объект Scala

      [{"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}]

Я пробовал gson, jerkson (оболочка Джексона Скала), sjson, flexjson.Никто из них не работал.У меня есть список клиентов.List [Customer].

Это самое близкое, что у меня есть:

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

Это дало мне 4 массива.Это, очевидно, не дало мне объект клиента, хотя.Я попробовал Джерксона.

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

Но я понял.

GenericSignatureFormatError occured : null

Я просто пытаюсь найти простой способ, как в Java.

Здесьмой класс Scala.

    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()
    }

}

Спасибо за любую помощь.

Ответы [ 8 ]

4 голосов
/ 01 ноября 2011

С помощью gson вы можете написать свой собственный 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))
3 голосов
/ 02 ноября 2011

Вы также можете попробовать Jerkson = Jackson + Scala
Довольно легко использовать, даже если у меня были проблемы со специальными полями JSON, содержащими "-"
Небольшое туто, которое я недавно видел в твиттере: http://logician.free.fr/index.php/2011/09/16/play-scala-and-json/

3 голосов
/ 01 ноября 2011

Я знаю, что с gson вам понадобится Array вместо scala.List. Я бы предложил сделать это. Вы должны использовать это с gson.fromJson, я думаю.

2 голосов
/ 02 ноября 2011

Я был безумен этим сейчас и попробовал GSON, Lift-Json, Sjson и, наконец, Jerkson , и нашел мир с этим.

Вот как я использую его в сочетании с 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/

1 голос
/ 02 ноября 2011

Помимо попыток создать Джерксона (это отличная библиотека для использования из того, что я слышал), вы также можете попробовать модуль Scala Джексона - модули являются официальным способом расширения работы Джексона для работы с ним.Типы данных сторонних производителей, а также нативные типы данных и конструкции других языков JVM.(это не значит, что он более официальный, чем Джексон, просто есть много полезных модулей расширения Jackson, с которыми многие разработчики не знакомы)

Проблемы с модулем Scala обсуждаются в основных списках рассылки Jackson (user @jackson.codehaus.org);возможно, вы нашли крайний случай, который можно исправить.

1 голос
/ 01 ноября 2011

Для этой цели я использую библиотеку json от Lift: она позволяет легко анализировать JSON и извлекать значения в классы дел. Он упакован в отдельную банку, поэтому вам не нужна вся платформа лифта для его использования.

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]]

Просто убедитесь, что любые дополнительные поля определены в классе case с использованием Option. Я заметил в вашем коде, что в объектах отсутствует поле user_id, что приведет к ошибке разбора, если поле user_id объявлено как Int вместо Option[Int].

0 голосов
/ 20 апреля 2018

Довольно просто с scala и библиотеками воспроизведения и кодом

import play.api.libs.json.{Format, Json}
case class Customer(name:String, city:String, address:String, id:Int)
object Customer {
   implicit val jsonFormat: Format[Customer] = Json.format(Customer)
}

val jsonDef = Json.parse(<json-string>)
val customers = jsonDef.as[List[Customer]]

customers - это список Customer объектов.

0 голосов
/ 17 мая 2013

Я написал анализатор / валидатор dsl, который позволяет вам явно разрешить любую проблему стирания типа.Из коробки он обрабатывает классы дел, кортежи, Option, Either, List, Map, joda DatetTime, конвейерную связь с функциями, многократное сопоставление клавиш и переназначение имен ключей.

Используется парсер Джексона

https://github.com/HigherState/jameson

...