You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Scala中format参数引发编译错误的解决方案问询

问题:openapi-generator生成的Scala代码因参数名冲突导致编译错误

我用openapi-generator生成了Scala代码,调用其中的registerApiOauth2方法时出现编译错误,具体代码和报错信息如下:

生成的AuthTokensApi代码

import examples.openverse.model.{InlineObject, OAuth2RegistrationSuccessful}
import examples.openverse.core.JsonSupport._
import sttp.client3._
import sttp.model.Method

object AuthTokensApi {
  def apply(baseUrl: String = "https://api.openverse.engineering/v1") = new AuthTokensApi(baseUrl)
}

def registerApiOauth2(format: String, data: InlineObject
): Request[Either[ResponseException[String, Exception], OAuth2RegistrationSuccessful], Any] =
    basicRequest
      .method(Method.POST, uri"$baseUrl/auth_tokens/register/?format=${ format }")
      .contentType("application/json")
      .body(data)
      .response(asJson[OAuth2RegistrationSuccessful])

JsonSupport实现代码

object JsonSupport extends SttpJson4sApi {
  def enumSerializers: Seq[Serializer[_]] = Seq[Serializer[_]]() :+
    new EnumNameSerializer(AudioReportRequestEnums.Reason) :+
    new EnumNameSerializer(ImageReportRequestEnums.Reason)

  private class EnumNameSerializer[E <: Enumeration: ClassTag](enum: E) extends Serializer[E#Value] {
    import JsonDSL._
    val EnumerationClass: Class[E#Value] = classOf[E#Value]

    def deserialize(implicit format: Formats): PartialFunction[(TypeInfo, JValue), E#Value] = {
      case (t @ TypeInfo(EnumerationClass, _), json) if isValid(json) =>
        json match {
          case JString(value) => enum.withName(value)
          case value => throw new MappingException(s"Can't convert $value to $EnumerationClass")
        }
    }

    private[this] def isValid(json: JValue) = json match {
      case JString(value) if enum.values.exists(_.toString == value) => true
      case _ => false
    }

    def serialize(implicit format: Formats): PartialFunction[Any, JValue] = {
      case i: E#Value => i.toString
      }
    }

  implicit val format: Formats = DefaultFormats ++ enumSerializers ++ DateSerializers.all
  implicit val serialization: org.json4s.Serialization = org.json4s.jackson.Serialization
}

编译报错信息

No implicit view available from examples.openverse.model.InlineObject => sttp.client3.BasicRequestBody.
      .body(data)
No org.json4s.Formats found. Try to bring an instance of org.json4s.Formats in scope or use the org.json4s.DefaultFormats.
.response(asJson[OAuth2RegistrationSuccessful])

问题根源

方法参数名format和JsonSupport中定义的隐式值format: Formats重名,导致局部参数遮蔽了全局的隐式实例,使得sttp无法找到将InlineObject转换为请求体所需的隐式转换,同时asJson也找不到需要的Formats隐式值。

解决方案

1. 重命名方法参数,保留查询参数名

将方法的参数名改为非冲突的名称(比如formatParam),但在uri中仍然使用format作为查询参数名:

def registerApiOauth2(formatParam: String, data: InlineObject
): Request[Either[ResponseException[String, Exception], OAuth2RegistrationSuccessful], Any] =
    basicRequest
      .method(Method.POST, uri"$baseUrl/auth_tokens/register/?format=${formatParam}")
      .contentType("application/json")
      .body(data)
      .response(asJson[OAuth2RegistrationSuccessful])

2. 显式指定隐式参数

在方法签名中显式声明所需的隐式参数,避免局部参数遮蔽全局隐式:

def registerApiOauth2(format: String, data: InlineObject
)(implicit jsonFormats: org.json4s.Formats = JsonSupport.format, jsonSerialization: org.json4s.Serialization = JsonSupport.serialization): Request[Either[ResponseException[String, Exception], OAuth2RegistrationSuccessful], Any] =
    basicRequest
      .method(Method.POST, uri"$baseUrl/auth_tokens/register/?format=${format}")
      .contentType("application/json")
      .body(data)
      .response(asJson[OAuth2RegistrationSuccessful])

3. 修改JsonSupport中的隐式值名称

将JsonSupport里的隐式format重命名为不冲突的名称(比如jsonFormats),并调整导入语句:
修改后的JsonSupport关键部分:

implicit val jsonFormats: Formats = DefaultFormats ++ enumSerializers ++ DateSerializers.all
implicit val serialization: org.json4s.Serialization = org.json4s.jackson.Serialization

调整导入语句:

import examples.openverse.core.JsonSupport.{jsonFormats, serialization}

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.19 04:30:56