简体   繁体   English

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

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

I have a case class which I want to serialize first. 我有一个我想先序列化的案例类。 Then after that, I want to deserialize it for storing purpose in MongoDB but java 8 LocalDateTime was creating problem. 之后,我想将它反序列化以便在MongoDB中存储,但java 8 LocalDateTime正在创建问题。 I took help from this link: how to deserialize DateTime in Lift but with no luck. 我从这个链接中获得了帮助: 如何在Lift中反序列化DateTime但没有运气。 I am unable to write it for java 8 date time. 我无法为java 8日期时间写它。 Can any one please help me with this date Time issue? 任何人都可以帮我解决这个日期时间问题吗? Here is my code: 这是我的代码:

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)

And here is the error message printed on the console: 这是控制台上打印的错误消息:

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

If I remove the dateTime parameter from case class, it works fine. 如果我从case类中删除dateTime参数,它可以正常工作。 It seems like the problem is in dateTime. 似乎问题出在dateTime上。

I ran your code on my Intellij Idea, got the same error. 我在我的Intellij Idea上运行了你的代码,得到了同样的错误。 Tried to debug the cause but the invocation stack is so deep that I finally gave up. 试图调试原因,但调用堆栈是如此之深,我终于放弃了。 But I guess maybe it is because Lift doesn't provide default Format for LocaleDateTime, just like the post you mentioned said, "it is the DateParser format that Lift uses by default." 但我想也许是因为Lift没有提供LocaleDateTime的默认格式,就像你提到的帖子所说的那样,“默认情况下,它是Lift使用的DateParser格式。”

Here is a compromise for your reference,Lift-JSON provides default Date format for us 以下是供您参考的折衷方案,Lift-JSON为我们提供了默认的日期格式

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

So instead of going all the way to write customized serializer, we may as well change our data type to fit the default Date format. 因此,我们可以改变我们的数据类型以适应默认的日期格式,而不是一直编写自定义序列化程序。 Plus, net.liftweb.mongodb.DateSerializer(Line 79) provides support for Date serialization. 另外,net.liftweb.mongodb.DateSerializer(第79行)提供了对日期序列化的支持。

Then, we can provide method to easily get LocaleDateTime. 然后,我们可以提供方法来轻松获取LocaleDateTime。 Following is how I try to figure it out. 以下是我试图解决的问题。

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

Anyway, hope it helps. 无论如何,希望它有所帮助。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM