/ / स्प्रे-जोसन में वैकल्पिक क्षेत्रों का प्रतिनिधित्व कैसे करें? - स्कैला, स्प्रे-ज्सन

स्प्रे-जेसन में वैकल्पिक फ़ील्ड का प्रतिनिधित्व कैसे करें? - स्कैला, स्प्रे-जेसन

मेरे पास मेरे अनुरोध पर एक वैकल्पिक फ़ील्ड है:

case class SearchRequest(url: String, nextAt: Option[Date])

मेरा प्रोटोकॉल है:

object SearchRequestJsonProtocol extends DefaultJsonProtocol {
implicit val searchRequestFormat = jsonFormat(SearchRequest, "url", "nextAt")
}

मैं अगली वैकल्पिक फ़ील्ड को कैसे चिह्नित करूं, जैसे कि निम्नलिखित JSON ऑब्जेक्ट्स को सही ढंग से पढ़ा और स्वीकार किया जाएगा:

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

मैं वास्तव में अशक्त मामले के बारे में परवाह नहीं करता,लेकिन अगर आपके पास विवरण है, तो अच्छा होगा। मैं स्प्रे-ज्सन का उपयोग कर रहा हूं, और इस धारणा के तहत था कि एक विकल्प का उपयोग करने से फ़ील्ड को छोड़ दिया जाएगा यदि यह ओरिजिनल बेन्सन ऑब्जेक्ट पर अनुपस्थित था।

उत्तर:

जवाब के लिए 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

मेरे लिए काम करता है (स्प्रे-जोन 1.1.1 स्कैला 2.9.1 बिल्ड)

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