【发布时间】:2018-08-08 11:54:11
【问题描述】:
我们使用的是akka-http,需要根据逻辑返回多个响应。这就是为什么,在我们的应用程序中,我们有这样的响应层次结构:
object CustomHttpResponse extends DefaultJsonProtocol {
implicit val formatter = new RootJsonWriter[CustomHttpResponse] {
override def write(obj : CustomHttpResponse) : JsValue = obj match
{
case success : Success =>
JsObject("type" -> "success".toJson, "value" -> success.toJson)
case failure : Failure =>
JsObject("type" -> "failure".toJson, "value" -> failure.toJson)
}
}
}
sealed trait CustomHttpResponse {
def status : Boolean
}
object Success extends SprayJsonSupport with DefaultJsonProtocol {
implicit val Formatter : RootJsonFormat[Success] = jsonFormat1(Success.apply)
}
case class Success(override val status : Boolean) extends CustomHttpResponse
object Failure extends SprayJsonSupport with DefaultJsonProtocol {
implicit val Formatter : RootJsonFormat[Failure] = jsonFormat3(Failure.apply)
}
case class Failure(override val status : Boolean, cause : String) extends CustomHttpResponse
这些响应是根据我的条件生成的,并由我的控制器辅助方法生成,如下所示:
def generateResponse(param1: String, param2: String): HttpResponse[CustomHttpResponse] = { .... }
HttpResponse 类的主体是自定义的:
case class HttpResponse[T <: CustomHttpResponse](statusCode : Int, body : T)
HttpResponse 类只是一种 DTO,它实际上是从控制器助手中获取值并返回给控制器。在控制器中,我们尝试从控制器辅助方法中获取值并将其设置为 akka http complele(.. ) 方法,如下所示:
val response = generateResponse("data", "data2")
complete(response.statusCode, response.body)
在将主体传递给完成方法时,我们得到这样的结果:
[ERROR] too many arguments for method complete: (m: => akka.http.scaladsl.marshalling.ToResponseMarshallable)akka.http.scaladsl.server.StandardRoute
[ERROR] complete(responseMessage.statusCode, responseMessage.body )
经过搜索,这个错误的原因是,我们的HttpResponse类包含了一个抽象类型,当我们把抽象类型的值赋给complete方法时,它无法弄清楚格式化程序是什么CustomHttpResponse。即使我们在 CustomHttpResponse 伴随对象中创建所有格式化程序。这方面的参考资料来自:
akka http (un)marshall traits 和 JsonFormat for abstract class with generic parameter
我觉得,我们错过了一些东西。那么,任何人都知道这是什么问题?处理这些sinerios的便捷方式是什么?
【问题讨论】: