在剧中请求正文到案例类转换&斯卡拉

时间:2015-03-30 08:34:44

标签: json scala playframework-2.0

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

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

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

我的请求主体json具有与case类完全相同的键名。例如:

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

  ]

}

案例类& req体键是相同的,那么可以直接从请求json构建case类对象吗?如果有可能那我该怎么办呢?任何参考都会有帮助。如果不可能那么这意味着我要定义我在answer中解释的自定义隐式转换器,其中我没有遇到任何问题。

注意:我正在使用Play 2.3& Scala 11用于我的开发

2 个答案:

答案 0 :(得分:9)

您可以非常轻松地使用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")
  )
}

答案 1 :(得分:1)

我们使用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]
      }
 }

按如下方式使用它将您的请求正文转换为案例类。

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

将caseclass转换为json,就像这样使用它。

JsonProvider.toJson(obj);

其中" obj"是案例类的对象。

Play-Json默认问题。

假设你有一个包含三个参数的案例类A,如下所示

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

如果您要解析的Json如下

{
name:"XYZ",
roll:22
}

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

但是使用fasterXML,您可以轻松地解析这个Json:

val a = JsonProvider.fromJsonA

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

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