使用 akka http unmarshall entity as case class 默认值时出错

Error when use akka http unmarshall entity as case class with default value

发送 http post 请求时发现错误:

The request content was malformed: No usable value for gender Did not find value which can be converted into java.lang.String

我的请求正文:

{
    "name":"test"
} 

我的 Scala 代码中的路由:

path("test"){
        (post(entity(as[People]) { req =>
          val resp = queryData(req)
          complete(resp.meta.getOrElse("statusCode", 200).asInstanceOf[Int] -> resp)
        }))
    } ~

People 的代码:

case class People(name: String, gender: String = "male")

为什么仍然出现 malformed 错误???

即使您设置了默认值,Json 的提取也会查找该字段,但该字段不存在,因此会失败。 (我假设您使用的是 spray-json,因为它是 akka-http 中的默认设置)

为了避免这个问题,同时保持简单,我建议您为创建人员的请求创建一个案例 class,其中包含该字段的 Option[String],并且您然后可以轻松地将 PeopleCreateRequest 转换为 People。

case class PeopleCreateRequest(name: String, gender: Option[String])

这将与框架一起很好地工作...

或者,如果您想保持这种设计,您需要考虑实施您自己的 JsonFormat[People],它将此值视为可选值,但在缺少时添加默认值.

看喷-jsonhttps://github.com/spray/spray-json#providing-jsonformats-for-other-types

但我想它会是这样的:

implicit val peopleFormat = new RootJsonFormat[People] {
    def read(json: JsValue): People = json match {
      case JsArray(Seq(JsString(name), JsString(gender))) =>
        People(name, gender)
      case JsArray(Seq(JsString(name))) =>
        People(name)
      case _ => deserializationError("Missing fields")
    }

    def write(obj: People): JsValue = ???
  }

我通常使用不同的 Json支持,使用 circe,但希望这能为您提供解决问题的方向