akka-highlevelhttp返回路由

yebdmbv4  于 2021-07-14  发布在  Java
关注(0)|答案(3)|浏览(329)

因为我有一个请求主体,所以我需要将其作为将来的请求,并在一个操作之后发送响应。但是,我需要检查主体是否有效,如果无效,我想返回一个badrequest状态。
我知道代码太多了,所以请看里面 requestFuture ,在恢复函数中是问题所在。

(pathPrefix("api" / "search") & post & extractRequest) { request =>
  val tokenResult = request.headers.find(x => x.name.toLowerCase == "token")
    tokenResult match {
      case None => throw new IllegalArgumentException(ServerMessages.TOKEN_NOT_FOUND)
      case Some(token) => token.value match {
        case this.apiToken => {
          val entity = request.entity
          val strictEntityFuture = entity.toStrict(2 seconds)
          val requestFuture = strictEntityFuture
              .map(_.data.utf8String.parseJson
                .convertTo[SearchFilters])

          requestFuture map { filters =>
             // here - I return an Route with data from controller
             complete(controller.searchData(filters)
               .map(_.toJson.prettyPrint)
               .map(toHttpEntity)))
          } recover (e => {
             // HERE IS THE PROBLEM
             // I need to return an Route, but here will be a Future[Route]
             complete(400 -> ServerMessages.INVALID_REQUEST_BODY)
          }
        }
        case _ => throw new IllegalArgumentException(ServerMessages.INVALID_TOKEN)
      }
}

我需要把将来的响应解包,或者用另一种方法抛出错误。
找到了一个解决方案 onComplete 指令,但我需要知道我的json是否成功转换,以便抛出自定义错误。

onComplete(requestFuture) {
    case Success(filters) => searchKpi(filters) ~
       pathEndOrSingleSlash {
           complete(403 -> ServerMessages.INVALID_METHOD_ARGUMENTS)
       }
    case Failure(ex) => failWith(ex) // returns 500 Internal Server Error
}

谢谢

m4pnthwp

m4pnthwp1#

您可以使用exceptionhandler。
像在文档中一样定义异常处理程序,并从异常中添加一个case(它应该与 failWith )到您需要返回的http状态(您提到 BadRequest )

case class MyBadException() extends RuntimeException

  implicit def myExceptionHandler: ExceptionHandler =
    ExceptionHandler {
      case MyBadException() => complete(HttpResponse(BadRequest)) // You decide the HTTP status to return
      case _ => complete(HttpResponse(InternalServerError, entity = "Bad numbers, bad result!!!"))
    }

    val route = path("test") {
      onComplete(getSomething()) {
        case Success(v) => complete("Ok")
        case Failure(err) => failWith(MyBadException())
      }
    }

注意,有两种方法可以附加异常处理程序
从文件中:

Bring it into implicit scope at the top-level.
Supply it as argument to the handleExceptions directive.
rwqw0loc

rwqw0loc2#

尝试以下操作:

val requestFuture = strictEntityFuture

requestFuture.map { entity =>
  entity.data.utf8String match {
  // Do your processing here
  case "" => RouteResult.Complete(HttpResponse(StatusCode.int2StatusCode(200), entity = HttpEntity("OK")))
}}.recover {
  case err: Throwable =>
  RouteResult.Complete(HttpResponse(StatusCode.int2StatusCode(500), entity = HttpEntity(err.getMessage)))
}
piwo6bdm

piwo6bdm3#

我已经有一个 Exception Handle r、 但只有两个病例( IllegalArgument 或者 NoSuchElement ). 多亏了ccheneson,我扩展了我的处理程序,可以返回一个 BadRequest 回应。但我做错了什么,因为我的 BadRequestException 已打包到 defaultExceptionHandler 路线。

val routes = (
    handleExceptions(noSuchElementExceptionHandler) &
      handleExceptions(tokenNotFoundExceptionHandler)) {
    domainRoutes
  }

private val domainRoutes = {
   onComplete(future) {
      case Success(values) => complete(controller.getdata(values))
      case Failure(e) => failWith(BadRequestExceptionHandler(e.getMessage))
   }
}

相关问题