[英]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數據中所有類型的編譯時安全性。 它還為您提供了一個很好的功能語法map
, flatMap
或orElse
等。這是一個巨大的優勢。
有關更多信息,請參閱此問
從理論上講,可以用默認的隱式參數來編寫函數
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.