Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/scala/16.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Scala `Future.failed`in of`transformWith[Array[Byte]]`给出了一个编译器错误_Scala_Akka_Future_Akka Http_Jackson Databind - Fatal编程技术网

Scala `Future.failed`in of`transformWith[Array[Byte]]`给出了一个编译器错误

Scala `Future.failed`in of`transformWith[Array[Byte]]`给出了一个编译器错误,scala,akka,future,akka-http,jackson-databind,Scala,Akka,Future,Akka Http,Jackson Databind,我正试图分析来自Akka的HttpResponse。理想的行为是,如果响应成功返回,则传递HttpEntity的Array[Byte]表示以进行处理。但是,如果状态返回为失败,则传递一个带有异常的Future.failed,其中包含状态代码和HttpEntity的JSON树表示形式。传递JSON树的原因是,有不同的服务器被这个抽象请求方法击中,并且它们的响应格式不同,所以我想在其他类中处理响应的解析 我尝试过对该工作流进行各种操作。直接抛出异常,而不是返回一个未来。失败将返回一个None值来代替

我正试图分析来自Akka的
HttpResponse
。理想的行为是,如果响应成功返回,则传递
HttpEntity
Array[Byte]
表示以进行处理。但是,如果状态返回为失败,则传递一个带有异常的
Future.failed
,其中包含状态代码和
HttpEntity的JSON树表示形式。传递JSON树的原因是,有不同的服务器被这个抽象请求方法击中,并且它们的响应格式不同,所以我想在其他类中处理响应的解析

我尝试过对该工作流进行各种操作。直接抛出异常,而不是返回一个
未来。失败
将返回一个
None
值来代替异常中的JSON树。其他方法也会产生类似的结果。当我
println(MAPPER.readTree(byteArray))
时,它会按照我的预期打印出响应,但随后在
BadRequestException
response
字段中返回
None

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)
我希望JsonNode的
BadRequestException
输出值为非none。相反,我在
Future.failed
上收到一个编译器错误,内容如下:

类型Future[Nothing]的表达式不符合预期的类型数组[Byte]


任何帮助都将不胜感激。

转换为字节后运行下一步时,请使用
flatMap
而不是
map

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).flatMap { byteArray =>
          if (response.status.isFailure()) Future.failed(new Exception("change this exception to one you had"))
          else Future.successful(byteArray)
        }
      case Failure(throwable) => Future.failed(new Exception("also here"))
    }
  }

由于您不想让
Future
计算失败,因此需要返回new
Future
。如果失败,您已经在执行
Future.failed
。缺少的部分也是将字节数组包装到
Future.successful
。当然,这是解决代码中类型编译错误的方法之一。

我将其标记为解决我的问题,因为它解决了编译器错误。没有解决异常中
MAPPER.readTree(byteArray)
为null的问题,但我自己设法解决了这个问题。我将
响应
转换为
选项[JsonNode]
默认设置为
None
。谢谢