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
相关产品推荐
相关产品推荐

