我们最近从Jerkson切换到json4s,我们很快发现这两个库的默认反序列化行为远非相同。
我们遇到的一个问题是我们有时会收到json输入,其中数字字段表示为字符串而不是数字
//example json object with string representation of "id"
{
"id" : "12545"
}
//example json object with number representation of "id"
{
"id" : 12345
}
这些需要反序列化到以下类
case class example(id:Int)
这是我们将json反序列化为任意类
的一般设置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]
}
}
但每当我们尝试使用id的字符串表示形式解析json对象时,它会抛出异常并显示消息:
优惠没有可用价值ID没有可用价值不知道怎么做 将JString(12545)转换为int
我一直在四处寻找为Integer字段设置自定义阅读器的方法,它尝试将字符串解析为整数,但我还没有找到涵盖我们用例的解决方案。我们需要的是一般的捕获所有解决方案,以支持遗留应用程序。
任何人都知道如何实现这一目标?
答案 0 :(得分:6)
谢谢,我最终得到了这个序列化程序对象:
object StringToLong extends CustomSerializer[Long](format => ({ case JString(x) => x.toLong }, { case x: Long => JInt(x) }))
implicit val formats = DefaultFormats + StringToLong
答案 1 :(得分:3)
我将发布我提出的解决方案,我使用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)
}
))