簡體   English   中英

如何在lift JSON中序列化和反序列化Java 8 dateTime?

[英]How to serialize and deserialize Java 8 dateTime in lift JSON?

我有一個我想先序列化的案例類。 之后,我想將它反序列化以便在MongoDB中存儲,但java 8 LocalDateTime正在創建問題。 我從這個鏈接中獲得了幫助: 如何在Lift中反序列化DateTime但沒有運氣。 我無法為java 8日期時間寫它。 任何人都可以幫我解決這個日期時間問題嗎? 這是我的代碼:

import net.liftweb.json.Serialization.{read, write}

implicit val formats = Serialization.formats(NoTypeHints) 

case class Child(var str: String, var Num: Int, var abc: Option[String], MyList: List[Int], val dateTime: LocalDateTime = LocalDateTime.now())
val ser = write(Child("Mary", 5, None, List(1, 2)))
println("Child class converted to string" + ser) 

var obj = read[Child](ser)
println("object of Child is " + obj)

這是控制台上打印的錯誤消息:

(run-main-0) java.lang.ArrayIndexOutOfBoundsException: 49938
java.lang.ArrayIndexOutOfBoundsException: 49938
    at com.thoughtworks.paranamer.BytecodeReadingParanamer$ClassReader.<init>(BytecodeReadingParanamer.java:451)
    at com.thoughtworks.paranamer.BytecodeReadingParanamer$ClassReader.<init>(BytecodeReadingParanamer.java:431)
    at com.thoughtworks.paranamer.BytecodeReadingParanamer$ClassReader.<init>(BytecodeReadingParanamer.java:492)
    at com.thoughtworks.paranamer.BytecodeReadingParanamer$ClassReader.<init>(BytecodeReadingParanamer.java:337)
    at com.thoughtworks.paranamer.BytecodeReadingParanamer.lookupParameterNames(BytecodeReadingParanamer.java:100)
    at com.thoughtworks.paranamer.CachingParanamer.lookupParameterNames(CachingParanamer.java:75)
    at com.thoughtworks.paranamer.CachingParanamer.lookupParameterNames(CachingParanamer.java:68)
    at net.liftweb.json.Meta$ParanamerReader$.lookupParameterNames(Meta.scala:89)
    at net.liftweb.json.Meta$Reflection$.argsInfo$1(Meta.scala:237)
    at net.liftweb.json.Meta$Reflection$.constructorArgs(Meta.scala:253)
    at net.liftweb.json.Meta$Reflection$.net$liftweb$json$Meta$Reflection$$findMostComprehensive$1(Meta.scala:266)
    at net.liftweb.json.Meta$Reflection$$anonfun$primaryConstructorArgs$1.apply(Meta.scala:269)
    at net.liftweb.json.Meta$Reflection$$anonfun$primaryConstructorArgs$1.apply(Meta.scala:269)
    at net.liftweb.json.Meta$Memo.memoize(Meta.scala:199)
    at net.liftweb.json.Meta$Reflection$.primaryConstructorArgs(Meta.scala:269)
    at net.liftweb.json.Extraction$.decompose(Extraction.scala:88)
    at net.liftweb.json.Extraction$$anonfun$1.applyOrElse(Extraction.scala:91)
    at net.liftweb.json.Extraction$$anonfun$1.applyOrElse(Extraction.scala:89)
    at scala.collection.immutable.List.collect(List.scala:305)
    at net.liftweb.json.Extraction$.decompose(Extraction.scala:89)
    at net.liftweb.json.Serialization$.write(Serialization.scala:38)
    at TestActor$.delayedEndpoint$TestActor$1(TestActor.scala:437)
    at TestActor$delayedInit$body.apply(TestActor.scala:54)
    at scala.Function0$class.apply$mcV$sp(Function0.scala:40)
    at scala.runtime.AbstractFunction0.apply$mcV$sp(AbstractFunction0.scala:12)
    at scala.App$$anonfun$main$1.apply(App.scala:76)
    at scala.App$$anonfun$main$1.apply(App.scala:76)
    at scala.collection.immutable.List.foreach(List.scala:383)
    at scala.collection.generic.TraversableForwarder$class.foreach(TraversableForwarder.scala:35)
    at scala.App$class.main(App.scala:76)
    at TestActor$.main(TestActor.scala:54)
    at TestActor.main(TestActor.scala)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:497)

如果我從case類中刪除dateTime參數,它可以正常工作。 似乎問題出在dateTime上。

我在我的Intellij Idea上運行了你的代碼,得到了同樣的錯誤。 試圖調試原因,但調用堆棧是如此之深,我終於放棄了。 但我想也許是因為Lift沒有提供LocaleDateTime的默認格式,就像你提到的帖子所說的那樣,“默認情況下,它是Lift使用的DateParser格式。”

以下是供您參考的折衷方案,Lift-JSON為我們提供了默認的日期格式

// net.liftweb.json.Serialization Line 72
def formats(hints: TypeHints) = new Formats {
  val dateFormat = DefaultFormats.lossless.dateFormat
  override val typeHints = hints
}

因此,我們可以改變我們的數據類型以適應默認的日期格式,而不是一直編寫自定義序列化程序。 另外,net.liftweb.mongodb.DateSerializer(第79行)提供了對日期序列化的支持。

然后,我們可以提供方法來輕松獲取LocaleDateTime。 以下是我試圖解決的問題。

package jacoffee.scalabasic

import java.time.{ ZoneId, LocalDateTime }
import java.util.Date

// package object defined is for Scala compiler to look for implicit conversion for case class parameter date
package object stackoverflow {
 implicit def toDate(ldt: LocalDateTime): Date =
   Date.from(ldt.atZone(ZoneId.systemDefault()).toInstant())

 implicit def toLDT(date: Date): LocalDateTime =
   LocalDateTime.ofInstant(date.toInstant(), ZoneId.systemDefault())
}


package jacoffee.scalabasic.stackoverflow

import java.time.LocalDateTime
import java.util.Date
import net.liftweb.json.{ NoTypeHints, Serialization }
import net.liftweb.json.Serialization.{ read, write }


case class Child(var str: String, var Num: Int, var abc: Option[String],
 myList: List[Int], val date : Date = LocalDateTime.now()) {
   def getLDT: LocalDateTime = date
 }

object DateTimeSerialization extends App {
   implicit val formats = Serialization.formats(NoTypeHints)

   val ser = write(Child("Mary", 5, None, List(1, 2)))
// Child class converted to string {"str":"Mary","Num":5,"myList":[1,2],"date":"2015-07-21T03:07:05.699Z"}
   println(" Child class converted to string " + ser)

   var obj=read[Child](ser)
   // Object of Child is Child(Mary,5,None,List(1, 2),Tue Jul 21 11:48:22 CST 2015)
   println(" Object of Child is "+ obj)
   // LocalDateTime of Child is 2015-07-21T11:48:22.075
   println(" LocalDateTime of Child is "+ obj.getLDT)
}

無論如何,希望它有所幫助。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM