You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

Scala Play WS 2.6请求方法返回类型不匹配及同步需求问题

解决Play WS 2.6返回类型不匹配及同步请求、令牌验证问题

先聊聊你遇到的编译错误原因:你的函数声明要返回Future[String],但实际代码既没有正确返回对应类型的值,还做了冗余操作。你调用Await.result(request, timeout)已经阻塞获取了请求结果,但之后只是定义了returner变量却没用到,最后函数没有任何返回语句,默认返回Unit,这就导致了类型不匹配的报错。

结合你提出的三个核心需求——返回String类型、同步请求、支持令牌验证,我给你两种可行的解决方案:

方案1:同步返回String(完全匹配你的同步需求)

如果必须要同步等待请求完成后再推进应用逻辑,直接返回String类型,可以这样修改代码:

import java.io.{File, InputStream}
import java.nio.file.Paths
import javax.inject._
import org.apache.commons.io.FileUtils
import play.api._
import play.api.http.HttpEntity
import play.api.libs.ws._
import play.api.mvc._
import scala.collection.mutable.ListBuffer
import scala.concurrent.Await
import scala.concurrent.duration._
import scala.concurrent.ExecutionContext
import sys.process._

@Singleton
class BuildService @Inject() (ws: WSClient, ec: ExecutionContext, config: Configuration) {

  def bbApiRequest(requestUrl: String, timeout: FiniteDuration): String = {
    // 从配置文件读取令牌,避免硬编码敏感信息
    val apiToken = config.get[String]("build.api.token")
    val request = ws
      .url(requestUrl)
      // 使用Bearer令牌验证替换基础认证
      .addHttpHeaders("Authorization" -> s"Bearer $apiToken")
      .get()

    // 同步等待请求完成,超时则抛出异常
    val response = Await.result(request, timeout)
    // 返回响应体的原始字符串,供后续反序列化使用
    response.body
  }
}

关键点说明:

  • 直接返回String类型,完美适配你后续用case class解析JSON的需求
  • Await.result阻塞当前线程,直到请求完成或超时,实现同步逻辑
  • 令牌验证通过添加Authorization请求头实现,这里用配置文件读取令牌的方式,比硬编码更安全
  • 如果请求超时,Await.result会抛出TimeoutException,你可以根据业务需求添加异常捕获逻辑

方案2:异步返回Future[String](如果后续需要非阻塞逻辑)

要是之后你想切换为非阻塞的异步处理,不需要同步阻塞,可以修正原来的函数,确保返回正确的Future[String]

def bbApiRequest(requestUrl: String, timeout: FiniteDuration): Future[String] = {
  val apiToken = config.get[String]("build.api.token")
  ws.url(requestUrl)
    .addHttpHeaders("Authorization" -> s"Bearer $apiToken")
    .get()
    // 将响应转换为字符串,匹配返回类型要求
    .map(_.body)
    // 添加超时控制,避免请求无限挂起
    .withTimeout(timeout)
}

关键点说明:

  • 去掉了Await.result,直接返回Future[String],由调用方决定是否阻塞等待结果
  • 使用map操作将WS响应转换为字符串,满足函数的返回类型要求
  • withTimeout方法可以确保请求在指定时间内完成,超时会触发TimeoutException

最后给你个安全小建议:永远不要在代码里硬编码密码或令牌,尽量通过配置文件、环境变量或者专业密钥管理工具来获取,避免敏感信息泄露。

内容的提问来源于stack exchange,提问作者crowgers

火山引擎 最新活动