在akka邮政路线上缺少FromRequestUnmarshaller [Entity]

时间:2016-11-07 16:00:11

标签: scala protocol-buffers akka-http scalapb

首先我要说的是,我对akka-http非常新,没有一本书能够很好地涵盖marsheling主题。所以对我来说这是一个黑盒子。我能够获得以下(Un)Marsheller,它能够根据请求头返回json和protobuf。

这部分代码工作正常,我有一个在akka-http中定义的get路由,它工作正常。

trait PBMarshaller {

  private val protobufContentType = ContentType(MediaType.applicationBinary("octet-stream", Compressible, "proto"))
  private val applicationJsonContentType = ContentTypes.`application/json`


  implicit def PBFromRequestUnmarshaller[T <: GeneratedMessage with Message[T]](companion: GeneratedMessageCompanion[T]): FromEntityUnmarshaller[T] = {
    Unmarshaller.withMaterializer[HttpEntity, T](_ => implicit mat => {
      case entity@HttpEntity.Strict(`applicationJsonContentType`, data) =>
        val charBuffer = Unmarshaller.bestUnmarshallingCharsetFor(entity)
        FastFuture.successful(JsonFormat.fromJsonString(data.decodeString(charBuffer.nioCharset().name()))(companion))
      case entity@HttpEntity.Strict(`protobufContentType`, data) =>
        FastFuture.successful(companion.parseFrom(CodedInputStream.newInstance(data.asByteBuffer)))
      case entity =>
        Future.failed(UnsupportedContentTypeException(applicationJsonContentType, protobufContentType))
    })
  }

  implicit def PBToEntityMarshaller[T <: GeneratedMessage]: ToEntityMarshaller[T] = {
    def jsonMarshaller(): ToEntityMarshaller[T] = {
      val contentType = applicationJsonContentType
      Marshaller.withFixedContentType(contentType) { value =>
        HttpEntity(contentType, JsonFormat.toJsonString(value))
      }
    }

    def protobufMarshaller(): ToEntityMarshaller[T] = {
      Marshaller.withFixedContentType(protobufContentType) { value =>
        HttpEntity(protobufContentType, value.toByteArray)
      }
    }

    Marshaller.oneOf(protobufMarshaller(), jsonMarshaller())
  }

}

我面临的问题是在邮政路线上。

(post & entity(as[PropertyEntity])) { propertyEntity =>
          complete {
            saveProperty(propertyEntity)
          }
      }

在编译期间,我收到以下错误

Error:(20, 24) could not find implicit value for parameter um: akka.http.scaladsl.unmarshalling.FromRequestUnmarshaller[PropertyEntity]
      (post & entity(as[PropertyEntity])) { propertyEntity =>

我不确定我到底错过了什么。我需要定义implicit FromRequestUnmarshaller吗?如果是的话应该有什么?

1 个答案:

答案 0 :(得分:0)

我能够一起破解可以工作的东西,但我仍然不知道如何创建一个可以解码任何ScalaPB案例类的通用Unmarshaller

implicit val um:Unmarshaller[HttpEntity, PropertyEntity] = {
    Unmarshaller.byteStringUnmarshaller.mapWithCharset { (data, charset) =>
        val charBuffer = Unmarshaller.bestUnmarshallingCharsetFor(data)
        JsonFormat.fromJsonString(data.decodeString(charBuffer.nioCharset().name()))(PropertyEntity)
        /*PropertyEntity.parseFrom(CodedInputStream.newInstance(data.asByteBuffer))*/
    }
  }

即便如此,我也不知道如何同时启用两个解码器。所以我评论了一个。