每当我创建接受Json主体的POST方法条目时,我都必须编写类似:
的内容req.body.validate[SomeBodyClassRepresentation].fold(
errors => logErrorAndReturnBadRequest(),
valid => handleRequest()
)
有没有办法减少那个样板,因为处理格式错误的json体几乎总是以同样的方式完成? 我正在考虑像ActionBuilder这样的东西,它可以适用于不同的Request类型。
答案 0 :(得分:1)
您可以创建一个包装错误处理行为的方法,如下所示:
def withParsedJsonRequest[T](actionBody: T => Future[Result])(
implicit reads: Reads[T], req: Request[JsValue]): Future[Result] = {
req.body.validate[T].fold(
invalid => { Future.successful(BadRequest("An error occured...")) }, // do error handling here!
valid => { actionBody(valid) })
}
并在Action
s:
def bla = Action.async(parse.json) { implicit req =>
withParsedJsonRequest[Bla] { b =>
Future.successful(Ok)
}
}
您必须将Reads
的隐式T
(用于解析JSON)传递给withParsedJsonRequest
函数,以及Request[JsValue]
(因此您不必重复它)。
名为“actionBody”的回调函数是您行动的核心。它需要解析T
并对其做一些事情。
我猜你可以自定义Action
,但为什么要打扰......
答案 1 :(得分:0)
如果你在范围内有一个隐含的Reads[T]
,并且同意使用Play的错误处理程序(你可以以某种方式自定义),那么有一个正文解析器可以完成你想做的事情:
def foo = Action(parse.json[T]) { request =>
val body: T = request.body
...
}
但是请注意,如果Content-Type
未设置为application/json
(没有与tolerantJson
等效的对象),则会返回400。