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

Scala带默认参数方法的@JsonIgnore未忽略合成方法序列化问题

解决Scala默认参数合成方法被Jackson序列化的问题

问题描述

在Scala中,给带默认参数的方法标注@JsonIgnore后,编译器会生成两个方法:原方法(已被@JsonIgnore忽略)和一个合成的默认参数方法(比如getSum$default$2)。但Jackson会序列化这个合成方法,导致输出中出现类似"sum$default$2":2的字段,需要让Jackson忽略这类合成方法。

解决方案

1. 使用Jackson Scala模块(推荐)

Jackson提供了专门的Scala模块,可自动处理Scala语言特性(包括合成方法、case类等),无需手动配置就能忽略默认参数生成的合成方法。

先添加依赖(以sbt为例):

libraryDependencies += "com.fasterxml.jackson.module" %% "jackson-module-scala" % "2.15.2"

修改代码注册模块:

import com.fasterxml.jackson.annotation.JsonIgnore
import com.fasterxml.jackson.databind.ObjectMapper
import com.fasterxml.jackson.module.scala.DefaultScalaModule

case class A(id: Int) {
  @JsonIgnore def getSum(a: Int, b: Int = 2): Int = a + b
}

@Test
def test(): Unit = {
  val a = A(5)
  val mapper = new ObjectMapper()
  mapper.registerModule(DefaultScalaModule)
  println(mapper.writeValueAsString(a)) // 输出:{"id":5}
}

2. 自定义过滤器忽略合成方法

如果不想引入额外模块,可自定义序列化修改器,过滤掉名称包含$default$的合成方法:

import com.fasterxml.jackson.annotation.JsonIgnore
import com.fasterxml.jackson.databind.ObjectMapper
import com.fasterxml.jackson.databind.ser.BeanPropertyWriter
import com.fasterxml.jackson.databind.ser.BeanSerializerModifier

case class A(id: Int) {
  @JsonIgnore def getSum(a: Int, b: Int = 2): Int = a + b
}

@Test
def test(): Unit = {
  val a = A(5)
  val mapper = new ObjectMapper()
  
  mapper.setSerializerModifier(new BeanSerializerModifier() {
    override def changeProperties(config, beanDesc, properties): java.util.List[BeanPropertyWriter] = {
      val iterator = properties.iterator()
      while (iterator.hasNext) {
        val writer = iterator.next()
        if (writer.getName.contains("$default$")) {
          iterator.remove()
        }
      }
      properties
    }
  })
  
  println(mapper.writeValueAsString(a)) // 输出:{"id":5}
}

3. 用@JsonIgnoreProperties指定忽略字段

直接在case类上标注注解,指定要忽略的合成方法名,适合单个类的场景:

import com.fasterxml.jackson.annotation.{JsonIgnore, JsonIgnoreProperties}
import com.fasterxml.jackson.databind.ObjectMapper

@JsonIgnoreProperties(value = Array("sum$default$2"))
case class A(id: Int) {
  @JsonIgnore def getSum(a: Int, b: Int = 2): Int = a + b
}

@Test
def test(): Unit = {
  val a = A(5)
  val mapper = new ObjectMapper()
  println(mapper.writeValueAsString(a)) // 输出:{"id":5}
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.20 06:45:33