Jackson如何限制REST API布尔字段仅接收true/false值
实现Jackson严格布尔字段解析方案
需求说明
REST API接收请求体时,settlementDiscountInfo对象下的showDiscountInfo字段需仅接受标准JSON布尔值true/false,禁止将数字、非标准字符串等其他类型值自动转换为布尔类型,传入非法类型值时直接抛出解析错误,字段未传时默认值为true。
当前Jackson默认开启宽松转换逻辑:非0数字、字符串"true"会被解析为true,0、字符串"false"会被解析为false,不符合参数校验预期。
可选实现方案
根据项目的规则适用范围,二选一即可:
方案1:全局配置严格标量解析(适合全项目统一要求严格类型校验的场景)
直接修改Spring内置的ObjectMapper配置,关闭标量类型的强制自动转换:
@Configuration public class JacksonConfig { @Bean public ObjectMapper objectMapper() { ObjectMapper objectMapper = new ObjectMapper(); // 关闭所有标量类型(数字、布尔、字符串)之间的自动强制转换 objectMapper.configure(DeserializationFeature.ALLOW_COERCION_OF_SCALARS, false); return objectMapper; } }
注意:该配置为全局生效,除布尔类型外,字符串转数字、数字转字符串等跨标量类型自动转换也会被禁用,比如传字符串
"123"给Integer类型字段也会抛出解析错误,使用前请确认全量接口兼容该严格校验规则。
方案2:单字段定制严格反序列化(仅对showDiscountInfo字段生效,无全局影响)
如果仅需要对当前字段做严格校验,不影响其他接口逻辑,可以给字段单独绑定自定义反序列化器,步骤如下:
- 编写严格布尔反序列化器,仅识别原生JSON布尔类型Token,其他类型直接抛出异常:
public class StrictBooleanDeserializer extends JsonDeserializer<Boolean> { @Override public Boolean deserialize(JsonParser p, DeserializationContext ctxt) throws IOException { JsonToken currentToken = p.currentToken(); if (currentToken == JsonToken.VALUE_TRUE) { return Boolean.TRUE; } if (currentToken == JsonToken.VALUE_FALSE) { return Boolean.FALSE; } throw ctxt.wrongTokenException(p, Boolean.class, JsonToken.VALUE_TRUE, "showDiscountInfo字段仅接受标准true/false布尔值,禁止传入数字、字符串等其他类型"); } }
- 修改原有实体类,绑定自定义反序列化器,移除影响赋值的Lombok注解:
@Data @NoArgsConstructor public static class SettlementDiscountInfoJson { private SettlementDiscountRequestInfo.DISCOUNT_SCHEME_TYPE discountScheme; private Integer taxAmount; @JsonProperty("settlementDiscounts") private List<SettlementDiscountJson> settlementDiscountJson; // 绑定严格反序列化器 @JsonDeserialize(using = StrictBooleanDeserializer.class) private Boolean showDiscountInfo = Boolean.TRUE; }
注意:原代码中
showDiscountInfo字段上的@Setter(AccessLevel.NONE)注解需要移除,否则Lombok不会为该字段生成setter方法,会导致传入合法false值时无法赋值,字段永远返回默认值true。如果需要避免业务代码手动修改该字段,将字段设为private即可,Jackson可通过反射完成字段赋值,不受访问修饰符限制。
校验效果
配置完成后,各类传值的处理逻辑符合预期:
- 传
"showDiscountInfo": true:正常解析为true - 传
"showDiscountInfo": false:正常解析为false - 传数字(0/1/其他数值)、字符串("true"/"false"/其他文本)、对象、数组等非布尔类型值:直接抛出JSON解析异常,返回参数错误提示
- 请求中不传该字段:保留默认值
true
内容的提问来源于stack exchange,提问作者iondevx
相关产品推荐
相关产品推荐

