为什么在java中你不需要创建这些json读/写?

pub*_*tic 4 java scala playframework

如果我错了,请纠正我,但是当使用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 _)
Run Code Online (Sandbox Code Playgroud)

Edm*_*984 11

您必须在Play中执行此操作的原因是框架设计选择,这是一个非常好的选择.

在Play中,该机制依赖于Scala implicits,这是一个非常强大的功能,可以使机制高度可插拔,在您调用的那一刻:

Json.toJson(Location(4.5, 5.3)) 
Run Code Online (Sandbox Code Playgroud)

编译器将查找与所需类型匹配的隐式范围.该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)
    }

}
Run Code Online (Sandbox Code Playgroud)

相反,在Spring中,这通常是通过内省和反思来完成的.您可能需要使用注释来帮助Spring确定如何从数据模型构建Json.结果是你不能改变它的完成方式,因此你的灵活性较低.

由于您可能不需要更多灵活性,因此许多Scala库/框架为您提供了生成所需类型类的默认实现的函数.额外的代码行

implicit val fmt = Json.format[Location]
Run Code Online (Sandbox Code Playgroud)

是你需要支付的价格,因为Play json序列化依赖于隐式.