Я пытаюсь проанализировать HttpResponse
от Акки.Идеальное поведение состоит в том, что если ответ возвращается успешно, передайте Array[Byte]
представление HttpEntity
вместе для обработки.Однако, если состояние возвращается как сбой, передайте Future.failed
с исключением, содержащим код состояния и представление дерева JSON HttpEntity
.Причина передачи дерева JSON состоит в том, что этот абстрактный метод запроса использует разные серверы, и они по-разному форматируют свои ответы, поэтому я хочу обработать синтаксический анализ ответа в этих других классах.
Я пытался различные манипуляции с этим рабочим процессом.Выдача исключения напрямую вместо возврата Future.failed
возвращает значение None
вместо дерева JSON в исключении.Другие методы дают похожие результаты.Когда я println(MAPPER.readTree(byteArray))
выводит ответ, как я ожидал, но затем возвращается None
в поле response
поля BadRequestException
.
import akka.http.scaladsl.model._
import akka.http.scaladsl.model.headers.Authorization
import akka.stream.Materializer
import com.fasterxml.jackson.databind.{DeserializationFeature, JsonNode, ObjectMapper}
import com.fasterxml.jackson.module.scala.DefaultScalaModule
import com.fasterxml.jackson.module.scala.experimental.ScalaObjectMapper
val MAPPER = new ObjectMapper with ScalaObjectMapper
MAPPER.registerModule(DefaultScalaModule)
MAPPER.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false)
def performQueryRaw(method: HttpMethod, uri: Uri, entity: Option[RequestEntity] = None, authorization: Option[Authorization] = None): Future[Array[Byte]] = {
val request: HttpRequest = HttpRequest(
method = method,
uri = uri,
entity = entity.getOrElse(HttpEntity.Empty),
headers = authorization.toList)
http.singleRequest(request).transformWith[Array[Byte]] {
case Success(response: HttpResponse) =>
convertEntityToBytes(response.entity).map { byteArray =>
if (response.status.isFailure()) Future.failed(BadRequestException(response.status, MAPPER.readTree(byteArray)))
else byteArray
}
case Failure(throwable) => Future.failed(RequestFailedException(throwable.getMessage + " -- " + uri.toString, throwable))
}
}
def convertEntityToBytes(entity: HttpEntity): Future[Array[Byte]] = {
entity.dataBytes.runFold[Seq[Array[Byte]]] (Nil) {
case (acc, next) => acc :+ next.toArray
}.map(_.flatten.toArray)
}
case class BadRequestException(status: StatusCode, response: JsonNode = None.orNull, t: Throwable = None.orNull) extends Exception(t)
case class RequestFailedException(message: String, t: Throwable = None.orNull) extends Exception(message, t)
Я ожидаю BadRequestException
со значением non-none для JsonNode.Вместо этого я получаю сообщение об ошибке компилятора Future.failed
, которое гласит:
Expression of type Future[Nothing] doesn't conform to expected type Array[Byte]
.
Любая помощь будет принята с благодарностью.