2016-05-25 6 views
5

Örnek sınıflar için özel json okuyucuları oluşturuyorum, ancak diğer durum sınıfında kullanılan List [T] için örtük JsonReader tipi sınıfı bulamıyorum.spray-json, JsonReader'ı liste için bulamıyor List [T]

DefaultJsonProtocol'u işaretlediğimde, koleksiyonlar için örtülü bir biçim zaten var;

implicit def listFormat[T :JsonFormat] = new RootJsonFormat[List[T]] { 
    def write(list: List[T]) = JsArray(list.map(_.toJson).toVector) 
    def read(value: JsValue): List[T] = value match { 
     case JsArray(elements) => elements.map(_.convertTo[T])(collection.breakOut) 
     case x => deserializationError("Expected List as JsArray, but got " + x) 
    } 
    } 

İşte basitleştirilmiş kod;

case class Test(i: Int, d: Double) 
case class ListOfTest(t: List[Test]) 

trait TestResultFormat extends DefaultJsonProtocol { 

    import CustomFormat._ 

    implicit object TestJsonFormat extends RootJsonReader[Test] { 

    override def read(json: JsValue): Test = { 

     val jsObject = json.asJsObject 
     val jsFields = jsObject.fields 

     val i = jsFields.get("i").map(_.convertTo[Int]).getOrElse(0) 
     val d = jsFields.get("d").map(_.convertTo[Double]).getOrElse(0d) 

     Test(i, d) 
    } 
    } 

    implicit object ListOfTestJsonFormat extends RootJsonReader[ListOfTest] { 

    override def read(json: JsValue): ListOfTest = { 

     val jsObject = json.asJsObject 
     val jsFields = jsObject.fields 

     val tests = jsFields.get("hs").map(_.convertTo[List[Test]]).getOrElse(List.empty) 

     ListOfTest(tests) 
    } 
    } 

} 

İşte hatalar; O sınırlama öğrendim

Error:(230, 53) not enough arguments for method convertTo: (implicit evidence$1: spray.json.JsonReader[List[com.xx.Test]])List[com.xx.Test]. 
Unspecified value parameter evidence$1. 
     val tests = jsFields.get("hs").map(_.convertTo[List[Test]]).getOrElse(List.empty) 
                ^
Error:(230, 53) Cannot find JsonReader or JsonFormat type class for List[com.xx.Test] 
     val tests = jsFields.get("hs").map(_.convertTo[List[Test]]).getOrElse(List.empty) 
               ^

cevap

3

Sorun DefaultJsonProtocol içinde List[T] için JsonReader temelde okumak ve ayrıca yazabilir anlamına gelen bir RootJsonFormat (bir RootJsonReader) olduğu gerçeğine ilgili olduğunu düşünüyorum. Yani, bir List[Item] okumayı denediğinizde, Item s yazmanız da mümkündür. Bu nedenle, RootJsonFormat'u kullanabilir ve yazmayı denediğinizde bir istisna atarsınız (desteklemediğinizden). Örneğin: Yalnızca okuyucuların kapsayan temiz bir çözümün farkında değilseniz

import spray.json._ 

implicit object TestJsonFormat extends RootJsonFormat[Test] { 

    override def read(json: JsValue): Test = { 

    val jsObject = json.asJsObject 
    val jsFields = jsObject.fields 

    val i = jsFields.get("i").map(_.convertTo[Int]).getOrElse(0) 
    val d = jsFields.get("d").map(_.convertTo[Double]).getOrElse(0d) 

    Test(i, d) 
    } 

    override def write(obj: Test): JsValue = serializationError("not supported") 
} 

, ben bu sorunu koştu çünkü kendimi bildirin yok ve başka bir şey bulamadı ediniz.

+0

Cevabınız için teşekkürler. Onu github sorunundan yeni öğrendim. Temiz çözüm için cevabımı kontrol edin, onun oldukça temiz olduğunu sanmıyorum ama yazma yöntemini her zaman geçersiz kılmak istemiyorum çünkü çok sayıda özel biçimlendiricimiz var, bu oldukça fazla bir yük oluşturuyor, bu yüzden bunu yapmak için bir temel özellik oluşturdum. –

+1

Görüyorum :) Uzun zaman önce bu problemi yaşadım ve sadece (kullanılmamış) yazma yöntemini geçersiz kılmaya alıştım. Teşekkürler. – ale64bit

3

sprey json geliyor:

sprey json 'ın tip sınıfı altyapı (Kök) JsonFormat türü değil, (Kök) JsonReader çevresinde oluşturulmuştur. Yani, sadece okuyor olsanız bile bir "Format" sağlamanız gerekecektir.

Check here.

sorunu aşmak için; Ben başka bir özellik oluşturdum RootJsonFormat okuyucu yerine genişletir ve temelde uygulanmayan yöntemle yazma yöntemini geçersiz kılar.

trait EmptyWriterFormat[T] extends RootJsonFormat[T] { 
    override def write(o: T): JsValue = ??? 
} 
İlgili konular