Playframework Any to Json - вариант использования: результат запроса anorm в Json

Я использую playframework 2.1.0 с Anorm для запроса базы данных. Я хочу сериализовать результат в json, не проходя через какие-либо промежуточные объекты/классы case.

вот как выглядит поток: Использование anorm:

DB.withConnection { implicit c =>
  val q = SQL(""" long query goes here """)
  q().toList
}

затем я беру этот результат и преобразовываю его из List[SqlRow] в List[Map[String,Any]]. String,Any — имя столбца, значение (Object/Any)

val asMap = info.toList.map(row => scala.collection.immutable.Map(row.asMap.toSeq:_*))

Я хотел бы jsonize это.

Я пробовал некоторые json-библиотеки: GSON, spray-json, playframework json lib. Но ни один из них, похоже, не работает с Any из коробки. Я попытался написать неявный модуль записи для типа Any с некоторым сопоставлением с образцом, но проблема в том, что этот модуль записи всегда опережает все остальные операции записи, поэтому json создается неправильно.

Советовать? Как бы вы предложили преобразовать результат из Anorm в Json? без каких-либо промежуточных моделей предметной области.


person samz    schedule 26.04.2013    source источник


Ответы (1)


нашел решение, не самое лучшее, используя FlexJson.
Раздражает то, что FlexJson не очень ориентирован на scala, поэтому коллекции scala и некоторые типы scala должны быть преобразованы в эквивалентный тип Java.

val info:List[SqlRow] = loadInfoFromDB using Anorm
//transform scala maps to java maps
val asMap: List[util.Map[String, Any]] = info.toList.map(row => JavaConversions.mapAsJavaMap(row.asMap))
//create the basic FlexJson serializer
val flexJson: JSONSerializer = new flexjson.JSONSerializer()
//register a Option transformer so it can serialize Options correctly
flexJson.transform(new flexjson.transformer.AbstractTransformer {
  def transform(`object`: Any) {
    `object`.asInstanceOf[Option[_]] match {
      case None => getContext.write("null")
      case Some(b:Any) => getContext.transform(b)
    }
  }
},classOf[Option[_]])
//finally convert the scala List to java List and use this serializer on it.
val infoJsn: String = flexJson.deepSerialize(JavaConversions.seqAsJavaList(asMap))
person samz    schedule 26.04.2013
comment
Мне начинает нравиться эта библиотека flexjson :) С некоторой дополнительной регистрацией преобразователей карты/списка scala вам не нужно все это предварительное преобразование типов scala в java. просто поместите все это в фабричный метод, который возвращает JSonSerializer, и вы получите полнофункциональный простой сериализатор json, который просто работает! - person samz; 29.04.2013