簡體   English   中英

為什么在java中你不需要創建這些json讀/寫?

[英]Why do you need to create these json read/write when in java you didn't have to?

如果我錯了,請糾正我,但是當使用Java和Spring MVC時,你不必創建這些額外的類來將你的Java類映射到JSON和JSON到類。

你為什么要在Play with Scala中這樣做? 它與Scala有關嗎?

case class Location(lat: Double, long: Double)

implicit val locationWrites: Writes[Location] = (
  (JsPath \ "lat").write[Double] and
  (JsPath \ "long").write[Double]
)(unlift(Location.unapply))


implicit val locationReads: Reads[Location] = (
  (JsPath \ "lat").read[Double] and
  (JsPath \ "long").read[Double]
)(Location.apply _)

您必須在Play中執行此操作的原因是框架設計選擇 ,這是一個非常好的選擇。

在Play中,該機制依賴於Scala implicits ,這是一個非常強大的功能,可以使機制高度可插拔 ,在您調用的那一刻:

Json.toJson(Location(4.5, 5.3)) 

編譯器將查找與所需類型匹配的隱式范圍。 Scala語言規范描述了解決implicits的算法,並且這種算法的設計方式使您可以在有限范圍內“ 導入 ”隱式。 由於這個功能,在程序的不同部分,您可以看到您的讀/寫或任何類型類的不同實現。

object MyImplicits {

    object ImplicitJson1{
        implicit val write:Write[Location] = "write to json all fields"
    }

    object ImplicitJson2{
        implicit val write:Write[Location] = "skip field a"
    }
}

object MyBusinessCode{

    def f1(location:Location){
        import MyImplicits.ImplicitJson1._
        Json.toJson(location)
    }
    def f2(location:Location){
        import MyImplicits.ImplicitJson2._
        Json.toJson(location)
    }

    def dynamicChoice(location:Location){
        implicit val write = {
            if(location.isEurope)           
                MyImplicits.ImplicitJson1.write
            else
                MyImplicits.ImplicitJson2.write
        }
        Json.toJson(location)
    }

}

相反,在Spring中,這通常是通過內省和反思來完成的。 您可能需要使用注釋來幫助Spring確定如何從數據模型構建Json。 結果是你不能改變它的完成方式,因此你的靈活性較低。

由於您可能不需要更多靈活性,因此許多Scala庫/框架為您提供了生成所需類型類的默認實現的函數。 額外的代碼行

implicit val fmt = Json.format[Location]

是你需要支付的價格,因為Play json序列化依賴於隱式。

你不需要:

case class Location(lat: Double, long: Double)

object Location {

  implicit val fmt = Json.format[Location]

}

Json.toJson(Location(4.5, 5.3)) // returns JsValue

當您的JSON結構與您的對象定義不匹配時,手寫的讀/寫/格式很有用。

既然你沒有提到你想要的JSON / Spring庫集成,我就是通過Jackson / Spring集成來舉例說明JSON。 我相信它利用了Java Beans字段命名約定。 這將涉及反射,並且在運行時發生。

但是,Play的Scala Json庫提供了JSON數據中所有類型的編譯時安全性。 它還為您提供了一個很好的功能語法mapflatMaporElse等。這是一個巨大的優勢。

有關更多信息,請參閱此問

https://softwareengineering.stackexchange.com/questions/228193/json-library-jackson-or-play-framework

從理論上講,可以用默認的隱式參數來編寫函數

def toJson[T](x: T)(implicit fmt: Reads[T] = Json.format[T]) = Json.toJson(x)(fmt)

但是在Play Json的情況下,它將無法工作,因為Json.format [T]是一個宏,它無法解析泛型類型符號T.它只能解析直接引用case類的符號或任何unapply(參見源代碼

另一方面,似乎可以編寫一個宏,它生成與我描述的相同的功能,但代替Apply(Json.format [T])使用來自JsMacroImpl.macroImpl的 AST(c,“format”,...) 。

無論如何,它不是語言限制 - 它只是沒有在給定的庫中實現。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM