【问题标题】:Getting Exception while converting case class to Json using Json4s使用 Json4s 将案例类转换为 Json 时出现异常
【发布时间】:2015-09-29 07:53:01
【问题描述】:

我正在尝试使用Json4s 将案例类转换为 Json 字符串。我得到了例外

MappingException:找不到类 java.lang.Object 的 ScalaSig

如果我只用另一个特征扩展我的案例类,就会发生这种情况。

我的代码如下:

trait Integration {
  val thirdpartyId: Option[Long]
}

trait HrIntegration extends Integration {
  override val thirdpartyId: Option[Long] = getValue
  def getValue = {
    Some(100L)
  }
}

case class Employee(id: Long, name: String, age: Long) extends HrIntegration


object Test extends App {
  import org.json4s.Extraction
  import org.json4s.jackson.JsonMethods._
  import org.json4s.DefaultFormats
  implicit lazy val serializerFormats = DefaultFormats
  val emp = Employee(1, "Yadu", 27)
  val jValue = Extraction.decompose(emp)
  val jsonString = compact(jValue)
  println(jsonString)
}

如果我将Option[Long] 转换为Option[BigInt],它可以正常工作。 Option[Double] 也有同样的问题。

当我通过堆栈跟踪和随后的谷歌搜索时,我发现问题出在反射上,因为 scala 版本不匹配。 所以我添加了scala反射库依赖如下:

"org.scala-lang" % "scala-reflect" % "2.11.7",
"org.scala-lang" % "scalap" % "2.11.7"

但即使在那之后,我也遇到了同样的错误。我现在已通过使用 BigIntBigDecimal 而不是 Long 和 Double 解决了这个问题。

谁能帮我理解这个问题,以及我如何通过使用 Long 和 Double 本身来解决它。

Json4s Version : 3.2.11
Scala Version : 2.11.7

【问题讨论】:

  • 如果您在Extraction.decompose(emp) 中向我们展示实际的 json 序列化可能会有所帮助。
  • 实际的 json 序列化是什么意思?我正在调用 org.json4s.Extraction 的 decompose() 方法,它采用 Any.
  • 你期待Extraction.decompose(emp)的结果是什么?

标签: json scala reflection json4s


【解决方案1】:

雅都,你应该添加自定义序列化的类。它可能看起来像

class EmployeeSerializer extends CustomSerializer[Employee](format => (
  {
    case JObject(JField("id", JInt(i)) :: JField("name", JString(n)) :: JField("age", JInt(a)) ::Nil) =>
      new Employee(i.longValue, n, a.longValue)
  },
  {
    case x @ Employee(i: Long, n: String, a: Long) =>
      JObject(JField("id", JInt(BigInt(i))) ::
        JField("name",   JString(n)) ::
        JField("age",   JInt(BigInt(a))) :: Nil)
  }
  ))

你也应该修改格式

implicit val formats = DefaultFormats + new EmployeeSerializer

所以,结果是:

import org.json4s._

trait Integration {
  val thirdpartyId: Option[Long]
}
trait HrIntegration extends Integration {
  override val thirdpartyId: Option[Long] = getValue
  def getValue = {
    Some(100L)
  }
}
case class Employee(id: Long, name: String, age: Long) extends HrIntegration

class EmployeeSerializer extends CustomSerializer[Employee](format => (
  {
    case JObject(JField("id", JInt(i)) :: JField("name", JString(n)) :: JField("age", JInt(a)) ::Nil) =>
      new Employee(i.longValue, n, a.longValue)
  },
  {
    case x @ Employee(i: Long, n: String, a: Long) =>
      JObject(JField("id", JInt(BigInt(i))) ::
        JField("name",   JString(n)) ::
        JField("age",   JInt(BigInt(a))) :: Nil)
  }
  ))

object Test extends App {
  import org.json4s.Extraction
  import org.json4s.DefaultFormats
  implicit val formats = DefaultFormats + new EmployeeSerializer
  val emp = Employee(1, "Yadu", 27)
  val jValue = Extraction.decompose(emp)
  println(jValue)
}

返回:

JObject(List((id,JInt(1)), (name,JString(Yadu)), (age,JInt(27))))

您可以在json4s项目的页面上找到更多信息:https://github.com/json4s/json4s#serializing-non-supported-types

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2020-07-13
    • 2016-07-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多