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




