/ / Як представити необов'язкові поля в спрей-джон? - скала, спрей-джон

Як представити необов'язкові поля в spray-json? - скала, спрей-джон

У моєму запиті є додаткове поле:

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.

Відповіді:

8 для відповіді № 1

Можливо, вам доведеться створити явний формат (попередження: psuedocodish):

object SearchRequestJsonProtocol extends DefaultJsonProtocol {
implicit object SearchRequestJsonFormat extends JsonFormat[SearchRequest] {
def read(value: JsValue) = value match {
case JsObject(List(
JsField("url", JsString(url)),
JsField("nextAt", JsString(nextAt)))) =>
SearchRequest(url, Some(new Instant(nextAt)))

case JsObject(List(JsField("url", JsString(url)))) =>
SearchRequest(url, None)

case _ =>
throw new DeserializationException("SearchRequest expected")
}

def write(obj: SearchRequest) = obj.nextAt match {
case Some(nextAt) =>
JsObject(JsField("url", JsString(obj.url)),
JsField("nextAt", JsString(nextAt.toString)))
case None => JsObject(JsField("url", JsString(obj.url)))
}
}
}

25 за відповідь № 2

Працює для мене (spray-json 1.1.1 scala 2.9.1 build)

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")))
}

6 за відповідь № 3

Використовуйте NullOptions ознака для відключення пропуску nullс: https://github.com/spray/spray-json#nulloptions Приклад: https://github.com/spray/spray-json/blob/master/src/test/scala/spray/json/ProductFormatsSpec.scala


0 для відповіді № 4

Не знаю, чи це допоможе вам, але ви можете дати це поле значення за замовчуванням у визначенні класу випадку, тому, якщо поле не в json, він призначить йому значення за замовчуванням.


0 для відповіді № 5

Легко

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)
}
}