我的请求是这样的application/json类型:{"able": true},但是当我发送这样的请求{"able":12345}时,字段able仍然可以获得正确的值true。为什么?

@PatchMapping("/{id}/path/{name}")
public ResponseEntity someMethod(
    @Valid @RequestBody SomeRequest request) {
    // do something
}

@Getter
@Setter
@NoArgsConstructor
@AllArgsConstructor
public class SomeRequest {
    @AssertTrue
    @NotNull
    private Boolean able;
}

最佳答案

因为当字段类型为bool时,jackson.databind会将int解析为bool。
NumberDeserializers.BooleanDeserializer中查找代码

            JsonToken t = p.getCurrentToken();
            if (t == JsonToken.VALUE_TRUE) {
                return Boolean.TRUE;
            }
            if (t == JsonToken.VALUE_FALSE) {
                return Boolean.FALSE;
            }
            return _parseBoolean(p, ctxt);


_parseBoolean(p, ctxt)会将int解析为bool。

我们可以自己做而不使用默认值。


创建我们的bool deser类。


public class MyDeser extends JsonDeserializer {
    @Override
    public Object deserialize(JsonParser p, DeserializationContext ctxt) throws IOException, JsonProcessingException {
        JsonToken t = p.getCurrentToken();
        if (t == JsonToken.VALUE_TRUE) {
            return Boolean.TRUE;
        }
        if (t == JsonToken.VALUE_FALSE) {
            return Boolean.FALSE;
        }
        return null;
        // not parse int to bool but null and it may work ok.
        // if throw new IOException(), it will work fail. Maybe return null means use other deser to deal it. throw Exception means fail. I don't know it clearly.
    }
}



创建一个配置并注入一个SimpleModule bean。我写申请书


 @SpringBootApplication
 @Configuration
 public class DemoApplication {
     @Bean
     public SimpleModule addDeser() {
         return new SimpleModule().addDeserializer(Boolean.class, new MyDeser());
     }
     public static void main(String[] args) {
         SpringApplication.run(DemoApplication.class, args);
     }
 }

07-27 13:46