Jackson MixIn未生效:YearWeek标量值JSON反序列化问题排查
问题
尝试使用Jackson结合自定义MixIn,将JSON标量字符串反序列化为threetenextra库中的YearWeek对象,编写的MixIn代码如下:
import org.threeten.extra.YearWeek; import com.fasterxml.jackson.annotation.JsonCreator; public class YearWeekMixIn { @JsonCreator public static YearWeek parse(String value) { return YearWeek.parse(value); } }
执行如下测试代码时失败:
public class YearWeekMixInTest { public record Foo(YearWeek yearWeek) {} @Test public void foo() throws JsonMappingException, JsonProcessingException { ObjectMapper objectMapper = new ObjectMapper(); objectMapper.addMixIn(YearWeek.class, YearWeekMixIn.class); objectMapper.readValue("{\"yearWeek\": \"2011-W01\"}", Foo.class); } }
抛出异常信息:
com.fasterxml.jackson.databind.exc.InvalidDefinitionException: Cannot construct instance of
org.threeten.extra.YearWeek(no Creators, like default constructor, exist): no String-argument constructor/factory method to deserialize from String value ('2011-W01')
请问MixIn中缺少什么配置,才能让Jackson识别并使用该注解方法完成反序列化?
解决方案
问题出在@JsonCreator注解的模式配置上。默认情况下Jackson会将该工厂方法视为参数化构造器,而非直接处理字符串标量的转换器。需要给@JsonCreator添加mode = JsonCreator.Mode.DELEGATING参数,明确告知Jackson这个方法采用委托模式创建对象,直接接收整个JSON标量值作为输入参数。
修正后的MixIn代码:
import org.threeten.extra.YearWeek; import com.fasterxml.jackson.annotation.JsonCreator; import com.fasterxml.jackson.annotation.JsonCreator.Mode; public class YearWeekMixIn { @JsonCreator(mode = Mode.DELEGATING) public static YearWeek parse(String value) { return YearWeek.parse(value); } }
原因说明
- 当JSON输入为标量字符串时,
DELEGATING模式会让Jackson直接把整个字符串传递给标注的工厂方法,完成对象实例化。 - 若不指定模式,Jackson默认使用
Mode.DEFAULT,会尝试将输入解析为键值对去匹配方法参数,而标量字符串无法满足这种匹配逻辑,因此抛出构造实例失败的异常。
内容的提问来源于stack exchange,提问作者SpaceTrucker
相关产品推荐
相关产品推荐

