千家信息网

STTP的基本使用方法是什么

发表于:2026-11-01 作者:千家信息网编辑
千家信息网最后更新 2026年11月01日,本篇内容介绍了"STTP的基本使用方法是什么"的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!如果使用
千家信息网最后更新 2026年11月01日STTP的基本使用方法是什么

本篇内容介绍了"STTP的基本使用方法是什么"的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!

如果使用 AkkaHttp 作为 STTP 的 backend 来并发地处理 list of url,就会得到类似 List[Future[Response[Either[ResponseError[io.circe.Error], T]]]],这样的结果。

一般地,我们更期望给上层调用者返回 Future[(List[Exception], List[T])]这样的类型。

下面代码演示了如何把:

List[Future[Response[Either[ResponseError[io.circe.Error], NasaData]]]]

准换为

Future[(List[Throwable], List[NasaData])]。

其中 tuple 的第一部分表示 response 中所有的 exception,第二部分表示所有正常数据。

几个技术关键点是:

1)Future.sequence 用于把 List[Future] 转为 Future[List]。

2)忽略 STTP Response 里除去 body 数据的其它部分,并把 response 转为 Either[Throwable, NasaData]。

3)经过步骤 1,2,数据类型已经是 Future[List[Either[Throwable, NasaData]]]。

4)List[Either[Throwable, NasaData]] 转为 (List[Throwable], List[NasaData])的思路是:

a) 构造一个空的 Tuple (List[Throwable(), List[NasaData]())作为一个累计器。

b) 使用 List.folderLeft()遍历元素,根据是 left 还是 right 累加到累计器的_1 或_2。

下面链接的文章演示了两种转换方式,一种是 Scala 原生手写,一种是使用 CAT。

但是,其中语句 case Left(err) => acc.left.map(_ => err) 的逻辑似乎与期望不符。如果 list of either 中有 Left,并不能工作。

  val erA: Either[String, Int] = Right(1)  val erB: Either[String, Int] = Right(2)  val erC: Either[String, Int] = Right(3)  val elA: Either[String, Int] = Left("error1")  val elB: Either[String, Int] = Left("error2")  val listOfEither = List(erA, elA, erB, erC, elB)  privateval eitherOfList: Either[String, List[Int]] = listOfEither.foldLeft(Right[String, List[Int]](List()).asInstanceOf[Either[String, List[Int]]])((acc, elem) => {    elem match {      case Right(v) => acc.map(l => l :+ v)      case Left(e) => acc.left.map(_ + e)    }  })  println(s"eitherOfList: $eitherOfList")

输出如下,并没有error部分的信息。

eitherOfList: Right(List(1, 2, 3))

下面的代码演示了并发发出100个RestAPi请求获取数据的处理代码,结果保存在Tuple里,分别是所有失败和成功的数据。

  import io.circe.generic.auto._  import sttp.client._  import sttp.client.akkahttp.AkkaHttpBackend  import sttp.client.circe._
import scala.concurrent.Future import scala.concurrent.duration._ import scala.concurrent.Await import scala.concurrent.ExecutionContext.Implicits.global
val NASA_API_KEY = "XXXXXXXXXXXXXXX" val baseUrl = s"https://api.nasa.gov/neo/rest/v1/neo/browse?api_key=${NASA_API_KEY}"
var pageSize = 10 var pageNumb = 100
case class Links(self: String, next: String) case class Page(number: Int, size: Int, total_elements: Int, total_pages: Int) case class NearEarthObject(absolute_magnitude_h: Double, designation: String) case class NasaData(links: Links, page: Page, near_earth_objects: List[NearEarthObject])
implicit val sttpBackend = AkkaHttpBackend() val listOfFutureResult: List[Future[Response[Either[ResponseError[io.circe.Error], NasaData]]]] = (0 until pageNumb).toList.map(pageIndex => { val pageUrl = s"http://www.neowsapp.com/rest/v1/neo/browse?page=$pageIndex&size=$pageSize&api_key=${NASA_API_KEY}" basicRequest.get(uri"$pageUrl") .response(asJson[NasaData]) .send() })
// Note: Future[List] --> List[Future] val futureOfList: Future[List[Response[Either[ResponseError[io.circe.Error], NasaData]]]] = Future.sequence(listOfFutureResult)
// Note: 把Response[Either[ResponseError[io.circe.Error], NasaData]] 转为了 Either[Throwable, NasaData] val respOfEither2Either: Response[Either[ResponseError[io.circe.Error], NasaData]] => Either[Throwable, NasaData] = resp => { println(s"resp==> code:${resp.code.code} ${resp.statusText}") val newEither: Either[Throwable, NasaData] = resp.body match { case Left(respErr) => Left(respErr.getCause) case Right(nasaData) => Right(nasaData) } newEither }
val futureOfListOfEither: Future[List[Either[Throwable, NasaData]]] = futureOfList.map(listOfResp => { listOfResp.map(respOfEither2Either) })
val listOfEither2TupleOfList: List[Either[Throwable, NasaData]] => (List[Throwable], List[NasaData]) = listE => { listE.foldLeft(List[Throwable](), List[NasaData]())((acc, eData) => { eData match { case Right(nasaData) => (acc._1, acc._2 :+ nasaData) case Left(t) => (acc._1 :+ t, acc._2) } }) }
val futureOfTupleOfList = futureOfListOfEither map listOfEither2TupleOfList
val result = Await.result(futureOfTupleOfList, 1.minute) println(s"Exceptions in Response: $result._1") println(s"Data in Response: $result._2")

另,Akka HTTP默认主机连接数是32个,所以需要修改applicaiton.confg配置以支持更多连接数。

akka.http.host-connection-pool.max-open-requests = 128

"STTP的基本使用方法是什么"的内容就介绍到这里了,感谢大家的阅读。如果想了解更多行业相关的知识可以关注网站,小编将为大家输出更多高质量的实用文章!

数据 代码 更多 演示 使用方法 方法 内容 文章 知识 类型 结果 部分 处理 期望 输出 实用 成功 学有所成 接下来 上层 数据库的安全要保护哪些东西 数据库安全各自的含义是什么 生产安全数据库录入 数据库的安全性及管理 数据库安全策略包含哪些 海淀数据库安全审计系统 建立农村房屋安全信息数据库 易用的数据库客户端支持安全管理 连接数据库失败ssl安全错误 数据库的锁怎样保障安全 互联网科技产业 科技互联网企业 云信互联网科技有限公司 互联网的科技创新 科技服务与互联网 高科技与互联网 小马过河互联网科技 上海喔噻互联网科技 中国的互联网科技企业的崛起 互联网科技寓意 受益于互联网科技的高速发展 互联网科技公司实习生 苏州铭阳互联网科技有限公司 互联网公司黑科技创始人 中科明德北京互联网科技 黑科技 体验场景 互联网大会 互联网公司高科技产品 工业互联网科技成果转化 银川新华互联网科技学校原画 中国主要互联网科技公司 互联网医疗科技 天下捷融互联网科技 蓝色互联网科技 安控科技rtu产品工业互联网 青岛中康互联网医疗科技有限公司 世界互联网科技公司市值排名 伊宁互联网科技做什么的 皮皮虾互联网科技有限公司 互联网科技包装股份有限公司上市 广州梦谷互联网科技有限公司领导
0