【问题标题】:Custom unpickler fails with "NoSuchElementException: : key not found: value"自定义 unpickler 失败并显示“NoSuchElementException: : key not found: value”
【发布时间】:2014-09-23 21:30:54
【问题描述】:

我正在尝试通过酸洗将 joda DateTime 实例与 json 进行酸洗/解酸。使用酸洗 0.8.0,如果我不提供自定义酸洗器,我会得到 ​​p>

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

并且 unpickling 失败并出现 NoSuchElementException: : key not found: value。使用酸洗 0.9.0-SNAPSHOT 我的 specs2 测试甚至不会终止。

【问题讨论】:

    标签: scala jodatime scala-pickling


    【解决方案1】:

    目前酸洗受到缺乏文档和无信息错误消息的影响。无论如何,我的 unpickle 方法的编写类似于this answer,并且它采用二进制序列化。通过反复试验找到的正确的 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
    }
    

    【讨论】:

      猜你喜欢
      • 2011-02-12
      • 1970-01-01
      • 2019-07-01
      • 1970-01-01
      • 2015-12-02
      • 2022-12-10
      • 1970-01-01
      • 2022-12-25
      • 2020-08-02
      相关资源
      最近更新 更多