Scala 如何在json中表示可选字段?

Scala 如何在json中表示可选字段?,scala,spray-json,Scala,Spray Json,我的请求中有一个可选字段: case class SearchRequest(url: String, nextAt: Option[Date]) 我的协议是: object SearchRequestJsonProtocol extends DefaultJsonProtocol { implicit val searchRequestFormat = jsonFormat(SearchRequest, "url", "nextAt") } 如何将nextAt字段标记为可选,以便正

我的请求中有一个可选字段:

case class SearchRequest(url: String, nextAt: Option[Date])
我的协议是:

object SearchRequestJsonProtocol extends DefaultJsonProtocol {
    implicit val searchRequestFormat = jsonFormat(SearchRequest, "url", "nextAt")
}
如何将nextAt字段标记为可选,以便正确读取和接受以下JSON对象:

{"url":"..."}
{"url":"...", "nextAt":null}
{"url":"...", "nextAt":"2012-05-30T15:23Z"}

实际上我并不真正关心空值的情况,但是如果您有详细信息,那就太好了。我使用的是spray json,我的印象是,如果原始json对象上没有该字段,则使用该选项将跳过该字段。

您可能必须创建一个显式格式(警告:psuedocdish):

适合我(spray json 1.1.1 scala 2.9.1构建)


使用
NullOptions
trait禁用跳过
null
s: 例子:

不知道这是否对您有帮助,但您可以在case类定义中为该字段指定默认值,因此如果该字段不在json中,它将为其指定默认值。

简单

import cc.spray.json._
trait MyJsonProtocol extends DefaultJsonProtocol {
  implicit val searchFormat = new JsonWriter[SearchRequest] {
    def write(r: SearchRequest): JsValue = {
      JsObject(
        "url" -> JsString(r.url),
        "next_at" -> r.nextAt.toJson,
      )
    }
  }
}

class JsonTest extends FunSuite with MyJsonProtocol {
test("JSON") {
    val search = new SearchRequest("www.site.ru", None)
    val marshalled = search.toJson
    println(marshalled)
  }
}

对于偶然发现这篇文章并希望更新弗朗索瓦·博索莱尔(François Beausoleil)关于Spray新版本(约2015年+?)的回答的任何人来说,JsField作为JsValue的公共成员不受欢迎;您应该只提供一个元组列表,而不是JsFields。不过,他们的答案很准确。

啊,我使用的是spray json 1.0.0和Scala 2.9.0.1。我想升级soonish,但我不在那里。然而谢谢你的回答!那对我不起作用。。。您需要配置什么吗?
import cc.spray.json._
import cc.spray.json.DefaultJsonProtocol._

// string instead of date for simplicity
case class SearchRequest(url: String, nextAt: Option[String])

// btw, you could use jsonFormat2 method here
implicit val searchRequestFormat = jsonFormat(SearchRequest, "url", "nextAt")

assert {
  List(
    """{"url":"..."}""",
    """{"url":"...", "nextAt":null}""",
    """{"url":"...", "nextAt":"2012-05-30T15:23Z"}""")
  .map(_.asJson.convertTo[SearchRequest]) == List(
    SearchRequest("...", None),
    SearchRequest("...", None),
    SearchRequest("...", Some("2012-05-30T15:23Z")))
}
import cc.spray.json._
trait MyJsonProtocol extends DefaultJsonProtocol {
  implicit val searchFormat = new JsonWriter[SearchRequest] {
    def write(r: SearchRequest): JsValue = {
      JsObject(
        "url" -> JsString(r.url),
        "next_at" -> r.nextAt.toJson,
      )
    }
  }
}

class JsonTest extends FunSuite with MyJsonProtocol {
test("JSON") {
    val search = new SearchRequest("www.site.ru", None)
    val marshalled = search.toJson
    println(marshalled)
  }
}