body解析器,用于根据请求正文返回结果



我想实现一个解析和验证request.body的 BodyParser,它基于 parse.json,目前看起来像这样:

def parseModel[A](implicit reads: Reads[A]): BodyParser[JsResult[A]] =
  parse.json.map(_.validate[A])

问题是它目前属于 BodyParser[JsResult[A]] 型,而我希望它是 BodyParser[A] 型。如果是JsError我希望它基本上返回带有验证错误的400 Bad Request

在Play API文档中,我找不到允许我检查先前正文解析器的结果并返回结果或继续控制器的方法。

BodyParser 在解析主体后,会产生一个Either[SimpleResult, A],其中SimpleResult是一个错误结果,应该立即返回,而不是处理动作。 BodyParser上的方便方法不允许你这样做,所以,创建一个委托给 JSON 身体解析器的新正文解析器:

def validateJson[A](implicit reads: Reads[A]) = new BodyParser[A] {
  def apply(request: RequestHeader) = parse.json(request).map(_.right.flatMap { json =>
    json.validate[A].asEither.left.map(e => BadRequest(JsError.toFlatJson(e)))
  })
}

您可以在此处看到,我们正在映射解析的结果,然后获取right值(成功的解析将JsValue),并对其调用flatMap。 我们的flatMap方法将JsResultvalidate转换为Either[JsError, A],所以我们用A完成了一半,之后我们mapJsErrorSimpleResult,我们就可以开始了。

好的

,我已经通过一种产生Action的方法实现了所需的行为:

def validateJson[A](implicit reads: Reads[A]) =
  parse.json.map(_.validate[A])

def ModelAction[A](action: A => Result)(implicit r: Reads[A]) =
  Action(validateJson[A]) { request =>
    request.body match {
      case JsSuccess(model, _) => action(model)
      case JsError(e) => BadRequest(JsError.toFlatJson(e))
    }
  }

我可以这样使用它:

def create = ModelAction[MyModel] { model =>
  ???
}

我仍然感兴趣,是否有可能对BodyParser做同样的事情,如果我需要这样做,或者像现在这样更好?

相关内容

  • 没有找到相关文章

最新更新