[英]SpringBoot atomically convert integer to boolean with @RequestBody annotation? How can I reject integer to be converted to boolean?
My request was an application/json
type like this: {"able": true}
, but when I send the request like this {"able":12345}
, the field able
still can get a correct value true
.我的请求是这样的
application/json
类型: {"able": true}
,但是当我发送这样的请求时{"able":12345}
,字段able
仍然可以获得正确的值true
。 Why?为什么?
@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;
}
Because jackson.databind will parse int to bool when field type is bool.因为当字段类型为 bool 时,jackson.databind 会将 int 解析为 bool。 Find code in
NumberDeserializers.BooleanDeserializer
在
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)
will parse int to bool. _parseBoolean(p, ctxt)
将 int 解析为 bool。
We can do it by ourselves not use default.我们可以自己做,不使用默认值。
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.
}
}
@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);
}
}
Actually the answer posted by sunsunsun is exactly.实际上, sunsunsun发布的答案正是如此。 It works well.
它运作良好。 But my answer is re-code the setter method of
SomeRequest
like this:但我的答案是重新编码
SomeRequest
的 setter 方法,如下所示:
public void setAble(Object value) {
if (value instanceof Boolean) {
submitted = (Boolean) value;
}
if ("true".equals(value)) {
submitted = true;
}
}
Because Jackson is using the setter method to inject value.因为 Jackson 是使用 setter 方法注入值。
create a Custom BooleanDeserializer by extending the JsonDeserializer from jackson library,通过从杰克逊库扩展 JsonDeserializer 创建自定义 BooleanDeserializer,
public class BooleanValueDeserializer extends JsonDeserializer<Boolean> {
@Override
public Boolean deserialize(JsonParser jsonParser, DeserializationContext ctxt) throws IOException, JacksonException {
try {
return jsonParser.getBooleanValue();
}catch(JsonParseException exception) {
throw new RuntimeException(String.format("%s is not a valid Boolean value for %s", jsonParser.getText(), jsonParser.getCurrentName()));
}
}
}
and add the following annotation on the Request Object for Deserialization并在请求对象上添加以下注释以进行反序列化
@Data
@AllArgsConstructor
@NoArgsConstructor
public class SomeRequest {
@NotNull
@JsonDeserialize(using = BooleanValueDeserializer.class)
private Boolean able;
}
Maybe because each non-zero integer value is true?也许是因为每个非零整数值都是真的? What happens if you sent
{"able":0}
?如果您发送
{"able":0}
会发生什么?
Each non zero value will be treated as true in boolean case.在布尔情况下,每个非零值都将被视为真。 If you send zero then it will set value to false.
如果你发送零,那么它会将值设置为 false。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.