如何为akka-http查询参数提供自定义反序列化器?

时间:2016-07-08 11:10:05

标签: akka-http

akka-http 2.4.7 reference表示可以自定义Deserializer来转换查询参数,而不将它们存储在中间变量中:

  

"amount".as[Int]将参数“amount”的值提取为Int,您需要在范围内使用匹配的反序列化器才能工作(另请参阅解组)

     

"amount".as(deserializer)使用显式反序列化器

提取参数“amount”的值

但是,该页面上的Deserialized parameter示例未显示自定义反序列化程序的使用方式。

如何定义一个,以便我可以说,例如.as[MyType]

我认为文档有问题,因为我找不到akka来源中提到的Deserializersearch

enter image description here

关于如何在Akka文档中排版Deserializer的屏幕截图。

2 个答案:

答案 0 :(得分:3)

Deserializer只是Unmarshallerakka-http 2.4.7的名称(akka-http 2.4.8相同)

修改:假设您正在提取名为type的查询参数,并且您希望Deserializer能够与type参数进行模式匹配StringMyType

您服务器应用中的route可能如下所示:

object MyServer {
  ...
  // Assuming that you're requiring a
  // `type` parameter from a `POST` request

  import MyType._

  val route =
    post {
      parameter('type.as(myTypeDeserializer)) { myTypeValue =>
        complete {
          // `myTypeValue` is already pattern-matched
          // to type `MyType` here thanks to `myTypeDeserializer`
          ...
        }
      }
    }
  ...
}

您的MyType对象可能如下所示:

object MyType {
  case object Type1 extends MyType
  case object Type2 extends MyType
  case object Type3 extends MyType

  import akka.http.scaladsl.unmarshalling.Unmarshaller

  // Here we pattern match the query parameter,
  // which has type `String`, to a `MyType`
  val stringToMyType = Unmarshaller.strict[String, MyType] {
    case "type1" => MyType.Type1
    case "type2" => MyType.Type2
    case "type3" => MyType.Type3
  }
}

如果用户请求不受支持的akka-http参数,则BadRequest会自动抛出type响应。

答案 1 :(得分:1)

我能够根据PredefinedFromStringUnmarshallers.scala内置示例声明自定义查询参数marshaller。

implicit val desId: Unmarshaller[String,Context.Id] = Unmarshaller.strict[String, Context.Id] { s =>
  Context.Id.parseOpt(s).getOrElse(
    if (s=="") throw Unmarshaller.NoContentException
    else throw new IllegalArgumentException( s"Not a valid id: '$s'" )
  )
}

明确提供返回类型似乎很重要。