简体   繁体   中英

how to convert JString to Int with json4s

we recently switched from Jerkson to json4s, we soon discovered that the default de-serialization behavior of these two libraries are far from the same.

one of the issues we're having is that we sometimes receive json input where a number field is represented as a string instead of a number

//example json object with string representation of "id"
{
    "id" : "12545"
}


//example json object with number representation of "id"
{
    "id" : 12345
}

these needs to get deserialized into the following class

case class example(id:Int)

this is our general setup for deserializing json into arbitrary classes

import org.json4s.native.Serialization._
import org.json4s._
import org.json4s.native.JsonMethods._

object Json {
    implicit val formats = DefaultFormats
    def parse[T](json:String)(implicit mf: Manifest[T]):T =  {
        org.json4s.native.JsonMethods.parse(input).extract[T]
    }
}

but whenever we attempt to parse the json object with string representation of the id it throws and exception with the message:

No usable value for offers No usable value for id Do not know how to convert JString(12545) into int

I've been looking around for a way to set a custom reader for Integer fields where it attempts to parse strings into Integers but I've yet to find a solution that covers our use case. What we need is a general catch all solution in order to support legacy applications.

Anyone know how to achieve this?

Thanks, I ended up with this serializer object:

object StringToLong extends CustomSerializer[Long](format => ({ case JString(x) => x.toLong }, { case x: Long => JInt(x) }))
implicit val formats = DefaultFormats + StringToLong

I'll just post the solution I came up with where I use a Custom Serializer for Integers

import org.json4s.native.Serialization._
import org.json4s._
import org.json4s.native.JsonMethods._
import org.json4s.native.Serialization._

object Json {

    implicit val formats = Serialization.formats(NoTypeHints) + new NumberSerializer()

    def parse[T](json:String)(implicit mf: Manifest[T]):T =  {
        org.json4s.native.JsonMethods.parse(input).extract[T]
    }
}

class NumberSerializer extends CustomSerializer[Int](format => (
    {
        case JInt(x) => x.toInt
        case JDouble(x) => x.toInt
        case JString(x) => x.toInt
    },
    {
        case x: Int => JInt(x)
    }
))

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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