【问题标题】:JsonProperty annotation does not work for Json parsing in Scala (Jackson/Jerkson)JsonProperty 注释不适用于 Scala 中的 Json 解析 (Jackson/Jerkson)
【发布时间】:2014-06-02 01:52:36
【问题描述】:

我需要解析下面的json字符串:

{“类型”:1}

我使用的案例类如下所示:

case class MyJsonObj(
    val type: Int
)

然而,这让 Scala 感到困惑,因为 'type' 是一个关键字。因此,我尝试使用 Jacson/Jerkson 的 @JsonProperty 注释,如下所示:

case class MyJsonObj(
    @JsonProperty("type") val myType: Int
)

但是,Json 解析器仍然拒绝在 json 中查找 'type' 字符串而不是 'myType'。以下示例代码说明了问题:

import com.codahale.jerkson.Json._
import org.codehaus.jackson.annotate._

case class MyJsonObj(
    @JsonProperty("type") val myType: Int
)

object SimpleExample {
  def main(args: Array[String]) {
    val jsonLine = """{"type":1}"""
    val JsonObj = parse[MyJsonObj](jsonLine)
}

我收到以下错误:

[error] (run-main-a) com.codahale.jerkson.ParsingException: Invalid JSON. Needed [myType], but found [type].

P.S:如上所示,我正在使用 jerkson/jackson,但如果这样可以让生活更轻松,我不介意切换到其他一些 json 解析库。

【问题讨论】:

    标签: json scala jackson jerkson


    【解决方案1】:

    使用反引号防止 Scala 编译器将 type 解释为关键字:

    case class MyJsonObj(
        val `type`: Int
    )
    

    【讨论】:

    • 虽然这样可行,但我真的在寻找 @JsonProperty 注释没有按预期工作的原因。另外,我希望 val 名称比“类型”更有意义。
    • 这可能是 Scala 将所有字段设为私有并自动生成 getter 和 setter 方法的问题。您也许可以使用 Scala 的meta annotations。如果将 @JsonProperty("type") 替换为 @(JsonProperty("type") @field @getter @setter) 会发生什么?
    【解决方案2】:

    我怀疑您没有在 Jackson 中正确启用 Scala 支持。

    我试过这个:

    object Test extends App {
    
      val mapper = new ObjectMapper
      mapper.registerModule(DefaultScalaModule)
      println(mapper.writeValueAsString(MyJsonObj(1)))
    
      val obj = mapper.readValue("""{"type":1}""", classOf[MyJsonObj])
      println(obj.myType)
    }
    
    case class MyJsonObj(@JsonProperty("type") myType: Int)
    

    我得到:

    {"type":1}
    1
    

    请注意,我通过调用 registerModule 为对象映射器添加了 Scala 支持

    【讨论】:

      【解决方案3】:

      正如@wingedsubmariner 所暗示的,答案在于Scala meta annotations

      这对我有用:

      import scala.annotation.meta.field
      
      case class MyJsonObj(
          @(JsonProperty @field)("type") val myType: Int
      )
      

      这是对 mapper.registerModule(DefaultScalaModule) 的补充,如果您要反序列化为 Scala 类,您可能会需要它。

      【讨论】:

        猜你喜欢
        • 2013-11-23
        • 1970-01-01
        • 2013-05-14
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多