在Play Framework中解析JSON到对象时如何动态选择类类型?

时间:2016-10-25 11:52:57

标签: scala playframework

以下示例代码使用Play Framework将JSON解析为对象:

  def createEvent(): Action[JsValue] = Action.async(parse.tolerantJson) {
    request => {
      request.body.validate[SomeEvent] match {
        case o:JsSuccess[SomeEvent] => {
          //do something
          Future(Created)
        }
      }
    }
  }

是否可以概括它以便它可以处理不同的事件类型? e.g。

  def createEvent(): Action[JsValue] = Action.async(parse.tolerantJson) {
    request => {
      val eventType = request.contentType match {
        case Some("SomeEventType") => SomeEvent
        case Some("OtherEventType") => OtherEvent
      }
      request.body.validate[eventType] match {
        case o:JsSuccess[eventType] => {
          //do something
          Future(Created)
        }
      }
    }
  }

目前,上述代码将在行request.body.validate[eventType]

中失败

2 个答案:

答案 0 :(得分:2)

您可以将def extract[T: JsonFormat](implicit req: Request[AnyContent]) = req.body.valudate[T] request.contentType match { case Some("SomeEventType") => extract[SomeEvent] case Some("OtherEventType") => extract[OtherEvent] } 提取到函数中,并使用适当类型的模式匹配结构调用它,即:

archivedTask

答案 1 :(得分:0)

您可以动态地从contentType读取和创建课程。但是你可能有问题,如果在范围内没有提取类型的隐式格式:

error: No Json formatter found for type A. Try to implement an implicit Format for this type.

java.lang.ClassNotFoundException: models.Bazz

可用数据:

  1. 模型

    包装模型

    案例类Bar(name:String)

  2. 请求

    request.contentType:Option [String] = Some(" models.Bar")

  3. 传入的身体

    request.body:JsValue =""" {" name":" bar name"}""& #34;

  4. 格式[巴]

    隐式val BarFormat = Json.format [models.Bar]

  5. 提取器:

    def extract[A <: Any](ct: String, json: JsValue)(implicit format: Format[A]) = {
    
      val manifest:Manifest[A] = Manifest.classType[A](Class.forName(ct))
    
      json.validate[A]
    }
    
    request.contentType.map(extract(_, request.body))
    
    res1: Option[play.api.libs.json.JsResult[models.Bar]] = Some(JsSuccess(Bar(bar name),/name))
    

    你可以看到https://github.com/strongtyped/fun-cqrs/blob/demos/shop-sample/samples/shop/src/main/scala/funcqrs/json/TypedJson.scala用于反序列化自包含json的其他方法。