我正在尝试使用喷雾在 Scala 中创建一个通用的 HTTP 客户端。这是类定义:
object HttpClient extends HttpClient
class HttpClient {
implicit val system = ActorSystem("api-spray-client")
import system.dispatcher
val log = Logging(system, getClass)
def httpSaveGeneric[T1:Marshaller,T2:Unmarshaller](uri: String, model: T1, username: String, password: String): Future[T2] = {
val pipeline: HttpRequest => Future[T2] = logRequest(log) ~> sendReceive ~> logResponse(log) ~> unmarshal[T2]
pipeline(Post(uri, model))
}
val genericResult = httpSaveGeneric[Space,Either[Failure,Success]](
"http://", Space("123", IdName("456", "parent"), "my name", "short_name", Updated("", 0)), "user", "password")
}
对象utils.AllJsonFormats
具有以下声明。它包含所有模型格式。在“另一端”使用相同的类,即我还编写了 API,并在那里使用了与 spray-can 和 spray-json 相同的格式化程序。
object AllJsonFormats
extends DefaultJsonProtocol with SprayJsonSupport with MetaMarshallers with MetaToResponseMarshallers with NullOptions {
当然,该对象具有对 models.api.Space、models.api.Failure 和 models.api.Success 序列化的定义。
类型看起来不错,即当Space
我告诉泛型方法它将接收并返回 aSpace
时,没有错误。但是,一旦我将 Either 带入方法调用,就会出现以下编译器错误:
找不到 spray.httpx.unmarshalling.Unmarshaller[Either[models.api.Failure,models.api.Success]] 类型的证据参数的隐式值。
我的期望是spray.json.DefaultJsonProtocol 中隐含的,即spray.json.StandardFormts 中的隐含内容,可以覆盖我。
以下是我的 HttpClient 类,尝试最好是通用的: 更新:更清晰/可重复的代码示例
object TestHttpFormats
extends DefaultJsonProtocol {
// space formats
implicit val idNameFormat = jsonFormat2(IdName)
implicit val updatedByFormat = jsonFormat2(Updated)
implicit val spaceFormat = jsonFormat17(Space)
// either formats
implicit val successFormat = jsonFormat1(Success)
implicit val failureFormat = jsonFormat2(Failure)
}
object TestHttpClient
extends SprayJsonSupport {
import TestHttpFormats._
import DefaultJsonProtocol.{eitherFormat => _, _ }
val genericResult = HttpClient.httpSaveGeneric[Space,Either[Failure,Success]](
"https://api.com/space", Space("123", IdName("456", "parent"), "my name", "short_name", Updated("", 0)), "user", "password")
}
有了上述,问题仍然出现在 unmarshaller 未解决的地方。帮助将不胜感激..
谢谢。