You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用Jackson注解映射JSON键至Scala Case Class属性反序列化报错

问题分析与解决方案

错误原因

你遇到的问题核心是混用了Jackson注解与json4s库:代码里使用json4s.Serialization.read进行反序列化,但给Case Class加的是Jackson的@JsonProperty/@JsonAlias注解——json4s无法识别这些Jackson专属注解,因此无法将JSON中的ageInInt字段映射到Case Class的age属性,最终抛出找不到age值的异常。


解决方案

根据你的需求,提供两种可行方案:

方案1:继续使用json4s(适配现有代码栈)

利用json4s自身的字段映射机制实现字段重命名,无需依赖Jackson注解。

方式A:自定义Format

直接实现json4s的Format trait,手动控制字段读写逻辑:

import org.json4s._
import org.json4s.jackson.Serialization

case class Person(name: String, age: Int)

val json =
  """{
    |"name": "Tausif",
    |"ageInInt": 30
    |}""".stripMargin

// 自定义Person的Format
implicit val personFormat: Format[Person] = new Format[Person] {
  override def reads(json: JValue): Person = {
    Person(
      name = (json \ "name").extract[String],
      age = (json \ "ageInInt").extract[Int]
    )
  }

  override def writes(person: Person): JValue = {
    JObject(
      "name" -> JString(person.name),
      "ageInInt" -> JInt(person.age)
    )
  }
}

// 反序列化
println(Serialization.read[Person](json))
方式B:使用FieldSerializer

通过json4s的FieldSerializer快速实现字段重命名,代码更简洁:

import org.json4s._
import org.json4s.jackson.Serialization
import org.json4s.FieldSerializer._

case class Person(name: String, age: Int)

val json =
  """{
    |"name": "Tausif",
    |"ageInInt": 30
    |}""".stripMargin

// 配置字段映射:将age <-> ageInInt互转
implicit val format: DefaultFormats.type = DefaultFormats + FieldSerializer[Person](
  renameTo("age", "ageInInt"),  // 序列化时把age转成ageInInt
  renameFrom("ageInInt", "age") // 反序列化时把ageInInt转成age
)

// 反序列化
println(Serialization.read[Person](json))

方案2:切换为Jackson Scala模块(保留Jackson注解)

如果想继续使用Jackson注解,需改用Jackson官方的Scala模块完成反序列化:

  1. 确保依赖中包含jackson-module-scala(比如sbt依赖:"com.fasterxml.jackson.module" %% "jackson-module-scala" % "2.15.2")
  2. 使用Jackson的ObjectMapper并注册Scala模块:
import com.fasterxml.jackson.databind.ObjectMapper
import com.fasterxml.jackson.module.scala.DefaultScalaModule
import com.fasterxml.jackson.annotation.JsonProperty

case class Person(name: String, @JsonProperty("ageInInt") age: Int)

val json =
  """{
    |"name": "Tausif",
    |"ageInInt": 30
    |}""".stripMargin

// 初始化Jackson ObjectMapper并注册Scala模块
val mapper = new ObjectMapper()
mapper.registerModule(DefaultScalaModule)

// 反序列化
val person = mapper.readValue(json, classOf[Person])
println(person)

内容的提问来源于stack exchange,提问作者Tausif Sayyad

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.19 06:30:48