0

我想创建一个自定义操作,它可以消除编写这样的操作的样板:

Action[MyClass](BodyParsers.parse.json[MyClass]) { req => ...

但是,我一直遇到类定义错误。这是我最成功的尝试:

class JsonAction[A: Reads] extends ActionBuilder[Request] {
  def hardcodedJson[A: Reads](action: Action[A]) = 
    Action.async(BodyParsers.parse.json[A]) { request => action(request) }

  def invokeBlock[A: Reads](request: Request[A], block: (Request[A]) => Future[Result]) = {
    block(request)
  }
  override def composeAction[A: Reads](action: Action[A]) = hardcodedJson(action)
}

但我收到以下错误:method composeAction overrides nothing.

如果我改成composeAction[A: Reads]composeAction[A]告诉我没有 A 类型的 Json 序列化器。

还有其他方法可以定义此自定义操作吗?

4

2 回答 2

1

ActionBuilder对于您的用例来说不够通用;你没有地方可以通过你的Reads[T].

不过也没什么特别的ActionBuilder。它是工厂方法apply的集合。async您可以使用所需的任何工厂方法定义自己的 Action 类型:

object JsonAction {
  def apply[A : Reads](request: Request[A] => Result) = Action(BodyParsers.parse.json[A])(request)
}

// these are equivalent:
Action[MyClass](BodyParsers.parse.json[MyClass]) { req => ??? }
JsonAction[MyClass] { req => ??? }
于 2016-04-23T23:17:00.390 回答
1

是的,我试图ActionBuilder 让它与官方的做法一起工作,只是无法让类型对齐。

不过,这对我有用:

object JsonActionHelper {
  def withReads[A](act: Request[A] => Future[Result])(implicit reads:Reads[A]) = 
    Action.async(BodyParsers.parse.json(reads))(act)
}

FooJson控制器中的用法(object包含隐式Reads[Foo]):

import models.FooJson._
import JsonActionHelper._

def handleIncomingFoo(fooId:String) = withReads[Foo] { req =>
  val foo:Foo = req.body
  ...
  Ok(...)
}
于 2016-04-18T06:51:29.483 回答