Spring WebFlux中Jackson反序列化FAIL_ON_NULL_FOR_PRIMITIVES配置不生效问题
WebFlux+Kotlin环境下Jackson反序列化缺失基本类型字段未触发报错的解决方法
问题背景
我需要让Jackson反序列化器在必填基本类型字段缺失时抛出错误,启用了FAIL_ON_NULL_FOR_PRIMITIVES规则,但无论通过application.yml还是自定义ObjectMapper Bean配置,都未生效——反序列化始终成功,Kotlin基本类型会被填充默认值。
相关代码如下:
- 待反序列化的数据类:
data class MyClass( val number : Int, val names: List<String> )
- 测试用JSON请求:
{ "names" : ["John", "Jim"] }
- 已尝试的
application.yml配置:
spring: application: name: my-app jackson: deserialization: FAIL_ON_NULL_FOR_PRIMITIVES: true
- 自定义
ObjectMapper配置:
@Configuration class JacksonConfig { @Bean fun objectMapper(): ObjectMapper? { return ObjectMapper().enable(DeserializationFeature.FAIL_ON_NULL_FOR_PRIMITIVES) } }
- 使用WebFlux RouterFunction的路由代码:
@Bean fun routes( handler : MyHandler ): RouterFunction<ServerResponse> { return router { ("/api/v1/" and (accept(MediaType.APPLICATION_JSON))) .nest { POST("route", handler::postData) } } }
- 处理器代码:
@Component class MyHandler( private val service: MyService ) { fun postData(request: ServerRequest): Mono<ServerResponse> { val body = request.bodyToMono(MyClass::class.java).log() val result = body.flatMap { req -> service.doThings(req) } return result.flatMap { ServerResponse.ok().contentType(MediaType.APPLICATION_JSON).bodyValue( "IT WORKED" ) } } }
原因分析
- 特性理解偏差:
FAIL_ON_NULL_FOR_PRIMITIVES仅处理字段存在但值为null的场景,而当前遇到的是字段完全缺失的情况,该特性不覆盖此场景。 - Kotlin模块默认行为:Jackson的Kotlin模块会自动为缺失的基本类型构造器参数填充默认值(如Int的0),绕过缺失字段的校验。
- WebFlux配置方式问题:单纯注册
ObjectMapperBean可能未被WebFlux的HTTP消息解码器(Jackson2JsonDecoder)正确使用,导致配置不生效。
解决方案
步骤1:启用正确的Jackson反序列化特性
需要同时启用两个特性:
FAIL_ON_NULL_FOR_PRIMITIVES:处理字段存在但值为null的情况FAIL_ON_MISSING_CREATOR_PROPERTIES:强制要求所有构造器参数(即data class的必填字段)必须存在于JSON中,缺失时抛出错误
方式一:通过application.yml配置
spring: application: name: my-app jackson: deserialization: FAIL_ON_NULL_FOR_PRIMITIVES: true FAIL_ON_MISSING_CREATOR_PROPERTIES: true
方式二:自定义WebFlux的HTTP消息解码器
如果yml配置仍不生效,直接配置WebFlux使用的Jackson2JsonDecoder,确保特性被正确应用:
@Configuration class WebFluxConfig : WebFluxConfigurer { override fun configureHttpMessageCodecs(configurer: ServerCodecConfigurer) { val objectMapper = ObjectMapper() // 注册Kotlin模块,必须保留以支持Kotlin数据类 .registerModule(KotlinModule()) .enable(DeserializationFeature.FAIL_ON_NULL_FOR_PRIMITIVES) .enable(DeserializationFeature.FAIL_ON_MISSING_CREATOR_PROPERTIES) // 替换默认的Jackson解码器和编码器 configurer.defaultCodecs().jackson2JsonDecoder(Jackson2JsonDecoder(objectMapper)) configurer.defaultCodecs().jackson2JsonEncoder(Jackson2JsonEncoder(objectMapper)) } }
步骤2:验证效果
发送缺失number字段的JSON请求后,Jackson会抛出MismatchedInputException,提示Missing required creator property 'number',反序列化失败,符合预期。
注意事项
- 确保data class的字段没有设置默认值(如
val number: Int = 0),否则FAIL_ON_MISSING_CREATOR_PROPERTIES会将其视为可选参数,不触发报错。 - 如果使用Spring Boot自动配置,确保自定义的
ObjectMapper或Jackson2JsonDecoder被Spring正确加载,避免冲突。
内容的提问来源于stack exchange,提问作者Karaja
相关产品推荐
相关产品推荐

