玩框架如何优雅地处理空体

时间:2016-04-09 21:11:07

标签: playframework

似乎请求正文类没有提供api(?)来检查调用者是否提供了任何正文,至少在使用the routing DSL时是这样。如果是期待JSON,它可能会很好:

  case PATCH(p"/foo") => Action { request =>
      val body: Option[JsValue] = request.body.asJson
      body match {
        case None =>
          Results.NoContent
        case Some(body) =>
          Results.Ok(s"got post request with body of length ${body.toString.length}")
      }
    }
  }

但永远不会到达Results.NoContent,并且在异常Invalid Json: No content to map due to end-of-input...之后向客户端发送“错误请求”响应。很高兴知道如何在调用者不包含正文的情况下发送http“无内容”响应。我可以想到首先转换为文本,然后再以Json作为解决方法。有什么清洁方式吗非常感谢!

2 个答案:

答案 0 :(得分:1)

您可以使用返回JsScuccess或JsError的验证函数。

 implicit request =>
    request.body.validate[ContractorRequest] match {
      case s: JsSuccess[ContractorRequest] =>
        val contractor = Contractor.fromRequest(s.get)
        contractorsService.update(contractor).map { contractor =>
          Ok(Json.toJson(contractor))
        }
      case e: JsError =>
        Future.successful(BadRequest(Json.toJson(ErrorWrapper("invalidJson", JsError.toJson(e).toString))))
    }

答案 1 :(得分:1)

回答您的具体问题:您必须自己检查一个空体。关于代码,不应该自动发送400。

您可以通过正文解析器将请求内容类型指定为json作为ActionAction.async的参数。 另外,可以通过类型参数在body解析器中指定要将JSON去连接的case类。

case class Foo(bar: String)
object Foo {
  implicit val format = Json.format[Foo]
}

...

case PATCH(p"/foo") => Action(parse.json[Foo]) { request =>
  val foo = request.body
  Ok(s"got valid request with $foo")
}

通过使用BadRequest

进行响应,处理具有无效JSON有效负载的请求

空身请求无效,应以BadRequest回复。 您可以在此处找到文档:https://www.playframework.com/documentation/2.6.x/api/scala/index.html#play.api.mvc.DefaultPlayBodyParsers