如何为Java 8 LocalDateTime编写自定义序列化程序

时间:2015-07-25 13:05:40

标签: java json scala scala-2.11 lift-json

我有一个名为HsvToRgb的类,我想使用Lift Json将其转换为JSON。一切正常我正在使用Child1但现在我想使用Java 8 joda date time但我无法为此编写自定义序列化器这里是我的代码

LocalDateTime

现在我想像这样使用Java 8 import org.joda.time.DateTime import net.liftweb.json.Serialization.{ read, write } import net.liftweb.json.DefaultFormats import net.liftweb.json.Serializer import net.liftweb.json.JsonAST._ import net.liftweb.json.Formats import net.liftweb.json.TypeInfo import net.liftweb.json.MappingException class Child1Serializer extends Serializer[Child1] { private val IntervalClass = classOf[Child1] def deserialize(implicit format: Formats): PartialFunction[(TypeInfo, JValue), Child1] = { case (TypeInfo(IntervalClass, _), json) => json match { case JObject( JField("str", JString(str)) :: JField("Num", JInt(num)) :: JField("MyList", JArray(mylist)) :: (JField("myDate", JInt(mydate)) :: JField("number", JInt(number)) ::Nil) ) => { val c = Child1( str, num.intValue(), mylist.map(_.values.toString.toInt), new DateTime(mydate.longValue) ) c.number = number.intValue() c } case x => throw new MappingException("Can't convert " + x + " to Interval") } } def serialize(implicit format: Formats): PartialFunction[Any, JValue] = { case x: Child1 => JObject( JField("str", JString(x.str)) :: JField("Num", JInt(x.Num)) :: JField("MyList", JArray(x.MyList.map(JInt(_)))) :: JField("myDate", JInt(BigInt(x.myDate.getMillis))) :: JField("number", JInt(x.number)) :: Nil ) } } Object Test extends App { case class Child1(var str:String, var Num:Int, MyList:List[Int], myDate:DateTime) { var number: Int=555 } val c = Child1("Mary", 5, List(1, 2), DateTime.now()) c.number = 1 println("number" + c.number) implicit val formats = DefaultFormats + new Child1Serializer val ser = write(c) println("Child class converted to string" + ser) var obj = read[Child1](ser) println("object of Child is "+ obj) println("str" + obj.str) println("Num" + obj.Num) println("MyList" + obj.MyList) println("myDate" + obj.myDate) println("number" + obj.number) }

LocalDateTime

我需要在自定义序列化程序类case class Child1(var str: String, var Num: Int, MyList: List[Int], val myDate: LocalDateTime = LocalDateTime.now()) { var number: Int=555 } 中进行哪些修改我试图这样做但我无法做到请帮助我

2 个答案:

答案 0 :(得分:1)

在序列化程序中,按如下方式序列化日期:

def serialize(implicit format: Formats): PartialFunction[Any, JValue] = {
case x: Child1 => 
  JObject(
    JField("str", JString(x.str)) :: JField("Num", JInt(x.Num)) ::
    JField("MyList", JArray(x.MyList.map(JInt(_)))) :: 
    JField("myDate", JString(x.myDate.toString)) :: 
    JField("number", JInt(x.number)) :: Nil
  )

}

在反序列化器中,

def deserialize(implicit format: Formats): PartialFunction[(TypeInfo, JValue), Child1] = {
case (TypeInfo(IntervalClass, _), json) => json match {
  case JObject(
    JField("str", JString(str)) :: JField("Num", JInt(num)) :: 
    JField("MyList", JArray(mylist)) :: (JField("myDate", JString(mydate)) :: 
    JField("number", JInt(number)) ::Nil)
  ) => {
    val c = Child1(
      str, num.intValue(), mylist.map(_.values.toString.toInt), LocalDateTime.parse(myDate)
    )
    c.number = number.intValue()
    c
  }
  case x => throw new MappingException("Can't convert " + x + " to Interval")
 }
}

LocalDateTime对象使用toString写入ISO格式,parse工厂方法应该能够从这样的字符串重建对象。

答案 1 :(得分:0)

您可以像这样定义 LocalDateTime 序列化程序。

class LocalDateTimeSerializer extends Serializer[LocalDateTime] {
  private val LocalDateTimeClass = classOf[LocalDateTime]

  def deserialize(implicit format: Formats): PartialFunction[(TypeInfo, JValue), LocalDateTime] = {
    case (TypeInfo(LocalDateTimeClass, _), json) => json match {
      case JString(dt) =>  LocalDateTime.parse(dt)
      case x => throw new MappingException("Can't convert " + x + " to LocalDateTime")
    }
  }

  def serialize(implicit format: Formats): PartialFunction[Any, JValue] = {
    case x: LocalDateTime => JString(x.toString)
  }
}

还要定义像这样的格式

implicit val formats = DefaultFormats + new LocalDateTimeSerializer + new FieldSerializer[Child1]

请注意使用 FieldSerializer 来序列化非构造函数,编号