Пользовательский unpickler завершается ошибкой с "NoSuchElementException:: ключ не найден: значение"

Я пытаюсь засолить / открепить экземпляр joda DateTime в / из json с помощью травления. С травлением 0.8.0, если я не поставляю специальный сборщик, я получаю

JSONPickle({
  "tpe": "org.joda.time.DateTime"
})

Когда я делаю:

class DateTimePickler(implicit val format: PickleFormat) extends
  SPickler[DateTime] with Unpickler[DateTime] {
    private val stringUnpickler = implicitly[Unpickler[String]]

    def pickle(picklee: DateTime, builder: PBuilder): Unit = {
      builder.beginEntry(picklee)
      builder.putField("date", b =>
        b.hintTag(stringTag).beginEntry(picklee.toString).endEntry()
      )
      builder.endEntry()
    }

    override def unpickle(tag: => FastTypeTag[_], reader: PReader): DateTime = {
      reader.hintTag(stringTag)
      val tag = reader.beginEntry()
      logger.debug(s"tag is ${tag.toString}")
      val value = stringUnpickler.unpickle(tag, reader).asInstanceOf[String] //can't debug NoSuchElementException: : key not found: value
      logger.debug(s"value is $value")
      reader.endEntry()

      val timeZone = DateTimeZone.getDefault
      DateTime.parse(value).withZone(timeZone) //otherwise the parsed DateTime won't equal the original
    }
  }

  implicit def genDateTimePickler(implicit format: PickleFormat) = new DateTimePickler

я получил

JSONPickle({
  "tpe": "org.joda.time.DateTime",
  "date": {
    "tpe": "java.lang.String",
    "value": "2014-09-16T17:59:25.865+03:00"
  }
})

и удаление не удается с NoSuchElementException:: ключ не найден: значение. С травлением 0.9.0-SNAPSHOT мой тест specs2 даже не закончится.

1 ответ

Решение

В настоящее время травление страдает от недостатка документации и неинформативных сообщений об ошибках. Во всяком случае, мой метод unpickle был написан аналогично этому ответу, и он предполагал двоичную сериализацию. Правильный метод unpickle, найденный методом проб и ошибок, выглядит следующим образом:

override def unpickle(tag: => FastTypeTag[_], reader: PReader): DateTime = {
  val dateReader = reader.readField("date")
  val tag = dateReader.beginEntry()
  val value = stringUnpickler.unpickle(tag, dateReader).asInstanceOf[String]
  dateReader.endEntry()

  val timeZone = DateTimeZone.getDefault
  DateTime.parse(value).withZone(timeZone) //otherwise the parsed DateTime won't equal the original
}
Другие вопросы по тегам