如何在使用操作(parse.json)时禁用HTML错误响应?

如何在使用操作(parse.json)时禁用HTML错误响应?,json,scala,playframework,playframework-2.4,Json,Scala,Playframework,Playframework 2.4,在使用Play Framework(2.4)实现的REST API中,我使用它来解析来自传入POST请求主体的JSON 使用我的当前代码(见下文) 发布缺少字段的有效JSON(例如,{“foo”:“})会产生 400,响应主体为{“error”:“缺少输入字段”}。这是好的,也是意料之中的 长html由默认的HttpErrorHandler生成。您可以通过以下方式提供您自己的。引用示例代码: 注意:如果在没有Guice的情况下管理依赖项,则必须在ApplicationLoader中提供自定义的

在使用Play Framework(2.4)实现的REST API中,我使用它来解析来自传入POST请求主体的JSON

使用我的当前代码(见下文)

  • 发布缺少字段的有效JSON(例如,
    {“foo”:“}
    )会产生
    400,响应主体为
    {“error”:“缺少输入字段”}
    。这是好的,也是意料之中的 长html由默认的
    HttpErrorHandler
    生成。您可以通过以下方式提供您自己的。引用示例代码:

    注意:如果在没有Guice的情况下管理依赖项,则必须在
    ApplicationLoader

    中提供自定义的
    HttpErrorHandler

    Json.parse
    委托给Jackson的
    parseJsValue
    ,它会引发异常。我不能正确地理解代码,为什么在
    Iteratee
    framework中不能正确地捕获异常

    最简单的解决方案是在
    ContentTypes.scala
    中复制代码,捕获
    Json.parse
    周围的异常,并正确地将其转换为
    BodyParser
    Iteratee
    值。不幸的是,Play不公开构建块,所以如果您想像在Play中那样进行复制粘贴,则需要大量复制粘贴

    或者,您可以对累积的bytearray执行dumb
    Iteratee.fold
    和direct
    Json.parse
    ,这不好;您可能希望检查accept标头,使用bytearray生成器,并限制输入的最大大小

    val betterJson: BodyParser[JsValue] = BodyParser("better json") { _request =>
      import play.api.libs.iteratee.Execution.Implicits.defaultExecutionContext
    
      Iteratee.fold(new Array[Byte](0)) { (bytes: Array[Byte], acc: Array[Byte]) =>
        bytes ++ acc
      } map { bytes =>
        val res: Either[Result, JsValue] = Try(Json.parse(bytes)) match {
          case Success(v) => Right(v)
          case Failure(e) => Left(BadRequest("bad json"))
        }
        res
      }
    }
    
    在控制器中使用
    betterJson

    def test = Action(betterJson) { request =>
      request.body.validate[Int].map(i => {
        Ok(i.toString)
      }).getOrElse(BadRequest("my error"))
    }
    
    通过以下方式进行测试:

    // works:
    // $ curl -H "Content-Type: application/json" -X POST -d '123' localhost:9000/test
    // 123
    // $ curl -H "Content-Type: application/json" -X POST -d '{}' localhost:9000/test
    // my error
    //
    // issue:
    // $ curl -H "Content-Type: application/json" -X POST -d '.' localhost:9000/test
    // bad json
    

    您是否尝试覆盖全局上的
    onError
    拦截器方法并捕获抛出的异常以自定义错误消息?我的应用程序中没有全局;这是最近的剧本版本。相反,提供才是出路。啊,我明白了。我使用play 2.4是的,我也是。在2.4(和2.5 afaik)中,仍然可以使用许多旧的API,但这些API已被弃用/不再推荐;看。官方例子:我觉得游戏对RESTAPI不友好。谢谢!我冒昧地在这里添加了代码示例。我使用Guice(Play 2.4+中的默认方法),因此没有问题。
    def test = Action(betterJson) { request =>
      request.body.validate[Int].map(i => {
        Ok(i.toString)
      }).getOrElse(BadRequest("my error"))
    }
    
    // works:
    // $ curl -H "Content-Type: application/json" -X POST -d '123' localhost:9000/test
    // 123
    // $ curl -H "Content-Type: application/json" -X POST -d '{}' localhost:9000/test
    // my error
    //
    // issue:
    // $ curl -H "Content-Type: application/json" -X POST -d '.' localhost:9000/test
    // bad json