sarah w
sarah w

Reputation: 3495

how to set value of attribute in a class and convert it into json using lift json

I have a class named Child which I want to convert into JSON using Lift Json. Everything is working fine, but the problem is I am setting the value of an attribute through a Scala setter but this new value is not stored in Json.

Here is the code :

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

The output printed on the console is :

number1
Child class converted to string{"str":"Mary","Num":5,"MyList":[1,2],"myDate":{}}
object of Child is Child1(Mary,5,List(1, 2),2015-07-24T14:04:09.266+05:00)
strMary
Num5
MyListList(1, 2)
myDate2015-07-24T14:04:09.266+05:00
number 555

Why is obj.number displaying value 555 ? It should print 1.

Upvotes: 2

Views: 398

Answers (1)

Vishal John
Vishal John

Reputation: 4382

Assuming that DateTime is Joda DateTime, you need to define a custom json serializer for serializing the DateTime object

Please refer to the section 'Serializing non-supported types' here

The serializer would look something like.

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
import net.liftweb.json.FieldSerializer


class JodaDateTimeSerializer extends Serializer[DateTime] {
  private val JodaDateTimeClass = classOf[DateTime]

  def deserialize(implicit format: Formats): PartialFunction[(TypeInfo, JValue), DateTime] = {
    case (TypeInfo(JodaDateTimeClass, _), json) => json match {
      case JInt(timemillis) => new DateTime(timemillis.longValue)
      case x => throw new MappingException("Can't convert " + x + " to DateTime")
    }
  }

  def serialize(implicit format: Formats): PartialFunction[Any, JValue] = {
    case x: DateTime => JInt(BigInt(x.getMillis))
  }
}

Also define your formats like this

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

Please note the usage of FieldSerializer to serialize the non-constructor filed, number

Upvotes: 2

Related Questions