2012-05-30 10 views
14

У меня есть дополнительное поле на мои просьбы:Как представить дополнительные поля в 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"} 

На самом деле, я действительно не забочусь о нулевом случае, но если у вас есть детали, было бы хорошо. Я использую спрей-json, и у меня создалось впечатление, что использование опции будет пропускать поле, если оно отсутствует на исходном объекте JSON.

ответ

8

Вы, возможно, придется создать явный формат (предупреждение: 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

Работы для меня (спрей-JSon 1.1.1 2.9.1 сборки Scala)

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

А, я использую spray-json 1.0.0, Scala 2.9.0.1. Я хочу скоро обновиться, но меня там нет. все же. Спасибо за Ваш ответ! –

+0

работает и для меня; игнорируйте другой ответ и обновите его. – iwein

0

Не знаю, поможет ли это вам, но вы можете присвоить этому полю значение по умолчанию в определении класса case, поэтому, если поле не находится в json, оно присваивает ему значение по умолчанию.

+0

Это не сработало для меня ... вам нужно что-то настроить? – samthebest