在 play 和 scala 中请求正文到案例 class 的转换

Request body to case class conversion in play & scala

我有一个案例 class 与此类似 found here :

case class WebCategory(topGroupName: String,
                       topGroupID: String,
                       webCategoryName : String,
                       webCategoryID : String,
                       subWebCats:Seq[SubWebCat])

case class SubWebCat(name:String, id:String)

我的请求正文 json 与案例 class 具有完全相同的键名。例如:

{
  "webCategoryID" : "blah",
  "webCategoryName" : "abcabc",
  "topGroupID" : "blah",
  "topGroupName" : "namehere",
  "subWebCats" : [
    {
      "name" : "blah",
      "id" : "idblah"
    },
            {
      "name" : "another blah",
      "id" : "another idblah"
    } 

  ]

}

case class 和 req 正文键相同,那么是否可以直接从请求 json 构建 case class 对象?如果可能的话,我该怎么做?任何参考资料都会有所帮助。如果不可能,那么这意味着我必须定义我在 answer 中解释的自定义隐式转换器,在其中实现它没有任何问题。

注意:我正在使用 Play 2.3 和 Scala 11 进行开发

我们使用FasterXml进行序列化和反序列化如下。

在您的 build.sbt

中包含此依赖项

"com.fasterxml.jackson.module" %% "jackson-module-scala" % "2.4.0-rc2"

创建两个辅助函数 toJson 和 fromJson 来序列化和反序列化

 object JsonProvider {
    
      //create mapper and register scala module
      private val mapper = new ObjectMapper
      mapper.registerModule(DefaultScalaModule)      
    
      def toJson(obj: Object): String = {
        val writer = new StringWriter
        mapper.writeValue(writer, obj)
        writer.toString
      }
    
      def fromJson[T: scala.reflect.Manifest](json: String): T = {
        mapper.readValue(json, scala.reflect.classTag[T].runtimeClass).asInstanceOf[T]
      }
 }

按如下方式将您的请求正文转换为大小写 class。

JsonProvider.fromJson[WebCategory](request.body.toString())

将大小写 class 转换为 json 像这样使用它。

JsonProvider.toJson(obj);

其中“obj”是案例 class 的对象。

播放问题-Json 默认值。

假设你有案例 class A 具有如下三个参数

case class A(id:String,name:String,roll:Int)

如果你的Json你想解析如下

{
name:"XYZ",
roll:22
}

你不能用 play-json 解析这个 Json 因为缺少字段或者一种方法是定义你的 Readwrite 函数很麻烦。

但是使用 fasterXML,您可以轻松地解析此 Json,例如:

val = JsonProvider.fromJsonA

您可以稍后将 Id 分配给 case class A,就像 val a1 = a.copy(id="xyz")

我遇到了这个问题然后我从 play-json 切换到 fasterXML 问题是 How to send Json from client with missing fields for its corresponding Case Class after using Json.format function

您可以很容易地使用 Play 的内置 JSON 验证。您不需要为此添加任何第三方依赖项。

case class WebCategory(topGroupName: String,
                       topGroupID: String,
                       webCategoryName : String,
                       webCategoryID : String,
                       subWebCats:Seq[SubWebCat])

object WebCategory {
  implicit val fmt = Json.format[WebCategory]
}

case class SubWebCat(name:String, id:String)

object SubWebCat {
  implicit val fmt = Json.format[SubWebCat]
}

然后,在您的控制器操作中:

def save: Action(parse.json) { implicit request =>
  request.body.validate[WebCategory].fold(
    errors => BadRequest(errors.mkString),
    category => Ok("saved category")
  )
}