Kotlin Spring Boot如何限制请求字段仅接收true/false布尔值
问题说明
需要实现接口请求的布尔字段仅接收true和false两种标准布尔值,拒绝其他可触发框架自动类型转换的非布尔入参。
当前框架默认的自动类型转换规则如下:
- 入参为
false、0、空字符串时,会被自动解析为false - 入参为
true、任意非零正负数字时,会被自动解析为true
即使字段已声明为Boolean类型,上述非标准入参依然可以正常通过解析,不符合校验要求,待改造的代码如下:
open class KdInfo : Info { @Min(0) var brutto: Long = 0 @NotNull var isRefund: Boolean = false // 该字段当前可接收非布尔类型的请求入参 }
实现方案
根据生效范围不同,有两种可选实现方式:
全局生效(推荐)
如果项目中所有布尔字段都需要做严格校验,直接配置Jackson反序列化规则即可,从反序列化根源拦截非布尔值,不需要给单个字段加额外注解。
- Spring Boot项目直接在配置文件中添加如下配置,可拦截数字类型转布尔的逻辑:
spring: jackson: deserialization: fail-on-numbers-for-booleans: true
- 非Spring Boot项目手动配置ObjectMapper特性:
val objectMapper = ObjectMapper() objectMapper.configure(DeserializationFeature.FAIL_ON_NUMBERS_FOR_BOOLEANS, true)
如果需要更严格的校验,连字符串形式的
"true"/"false"也一并拦截,只允许JSON原生布尔字面量传入,可以自定义严格反序列化器注册为Jackson全局的Boolean类型反序列化器即可。
配置开启后,Jackson遇到不符合要求的非布尔类型值转Boolean的场景,会直接抛出反序列化异常,接口返回400参数错误。
单字段生效
如果仅需要对isRefund字段做严格校验,不影响其他字段的原有逻辑,可以自定义严格布尔反序列化器,再通过注解绑定到对应字段上。
- 编写严格反序列化逻辑,仅允许标准JSON布尔值通过:
import com.fasterxml.jackson.core.JsonParser import com.fasterxml.jackson.core.JsonToken import com.fasterxml.jackson.databind.DeserializationContext import com.fasterxml.jackson.databind.deser.std.StdDeserializer class StrictBooleanDeserializer : StdDeserializer<Boolean>(Boolean::class.java) { override fun deserialize(p: JsonParser, ctxt: DeserializationContext): Boolean { return when (p.currentToken) { JsonToken.VALUE_TRUE -> true JsonToken.VALUE_FALSE -> false else -> throw ctxt.wrongTokenException( p, Boolean::class.java, JsonToken.VALUE_TRUE, "字段仅支持传入true或false标准布尔值" ) } } }
- 在目标字段上添加
@JsonDeserialize注解,指定使用上述自定义反序列化器:
open class KdInfo : Info { @Min(0) var brutto: Long = 0 @NotNull @com.fasterxml.jackson.databind.annotation.JsonDeserialize(using = StrictBooleanDeserializer::class) var isRefund: Boolean = false }
注意:不要尝试仅通过Bean Validation(如
@AssertTrue/@AssertFalse)实现该需求,这类校验注解执行时,框架已经完成了非布尔值到布尔值的自动转换,拿到的已经是转换后的true/false,无法识别原始入参是否为非布尔类型。
内容的提问来源于stack exchange,提问作者Anton Zotin
相关产品推荐
相关产品推荐

