3

我们最近从 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 对象时,以及带有消息的异常:

offer 没有可用值 id 没有可用值 不知道如何将 JString(12545) 转换为 int

我一直在寻找一种为整数字段设置自定义阅读器的方法,它试图将字符串解析为整数,但我还没有找到涵盖我们用例的解决方案。我们需要的是一个通用的包罗万象的解决方案,以支持遗留应用程序。

任何人都知道如何实现这一目标?

4

2 回答 2

6

谢谢,我最终得到了这个序列化程序对象:

object StringToLong extends CustomSerializer[Long](format => ({ case JString(x) => x.toLong }, { case x: Long => JInt(x) }))
implicit val formats = DefaultFormats + StringToLong
于 2015-02-05T16:56:13.353 回答
4

我将发布我想出的解决方案,其中我使用自定义序列化程序用于整数

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)
    }
))
于 2014-11-19T14:11:40.627 回答