对于url编码的POST参数,你如何为json对象unmarshaller实现String?

时间:2013-08-03 03:23:37

标签: scala spray

如何为url编码的POST参数实现String到json对象unmarshaller?我正在使用1.2版本。

这就是我想要的。 Foursquare将url编码的POST推送到我的服务。我的路线看起来像这样

  path("handle_4sq_push") {
    formFields("checkin".as[FsqCheckin], "user".as[String], "secret".as[String]) {
      (checkin, user, secret) =>
        complete {
          StatusCodes.OK
        }
    }
  } 

我有FsqCheckin的json解析器,其定义如下

  implicit val fsqCheckinFormat = jsonFormat(FsqCheckin.apply, "id", "createdAt", "timeZoneOffset", "user", "venue")

所以这一切都很好,但只有在参数是表格编码时它才有效。否则Spra​​y说

There was a problem with the requests Content-Type:
Field 'checkin' can only be read from 'multipart/form-data' form content

所以我以为我会写unmarshaller。我写了这个

  implicit def MyJsonUnmarshaller[T: RootJsonReader] =
    Unmarshaller.delegate[String, T](ContentTypes.`*`) {
      value => {
        val json = JsonParser(value)
        json.convertTo[T]
      }
    }

但如果我把它带到我的路线范围内,我会得到以下编译错误

too many arguments for method formFields: (fdm: spray.routing.directives.FieldDefMagnet)fdm.Out
        formFields("checkin".as[FsqCheckin], "user".as[String], "secret".as[String]) {
                  ^

如果我在范围内没有FsqCheckin的json解析器,那就是同样的错误。

我该如何处理这个问题?

1 个答案:

答案 0 :(得分:1)

令人震惊的是我自己弄明白了。这是通用unmarshaller的工作版本。

implicit def String2JsonParser[T: RootJsonReader] = new FromStringDeserializer[T] {
  def apply(value: String) =
    try
      Right(JsonParser(value).convertTo[T])
    catch {
      case ex: Throwable => Left(spray.httpx.unmarshalling.MalformedContent(ex.getMessage))
    }
}