spring Long 值的引导验证
spring boot validation for Long values
这是 class 我们要映射传入请求
@Getter
@Setter
public class FooRequest {
@Size(max = 255, message = "{error.foo.name.size}")
private String name;
@Digits(integer = 15, fraction = 0, message = "{error.foo.fooId.size}")
private Long fooId;
@Digits(integer = 15, fraction = 0, message = "{error.foo.barId.size}")
private Long barId;
}
我已经像上面那样使用了javax.validation.constraints.*
。如果我们发送像
这样的请求
{
"name": "Test",
"fooId": "0001234567",
"barId": "0003456789"
}
然后它工作正常,我们能够将结果保存在数据库中,但是如果我们像这样发送它:
{
"name": "Test",
"fooId": 0001234567,
"barId": 0003456789
}
然后我们得到 400 Bad Request
。我不明白我在做什么错,我只是想确保用户发送长度在 1-15 之间的数字,并希望将其映射到 Long
变量。是因为 fraction
还是因为所有这些值都以 0 开头?
第二个 JSON 是 而不是 一个 valid json 因为前导零。
背景
Spring 使用 Jackson 库进行 JSON 交互。
如果您尝试解析第二个 JSON:
,则 Jackson 的 ObjectMapper
默认会抛出异常
public class Main {
public static void main(String[] args) throws IOException {
ObjectMapper objectMapper = new ObjectMapper();
objectMapper.readValue("{\"name\": \"Test\", \"fooId\": 0001234567, \"barId\": 0003456789}", FooRequest.class);
}
}
例外情况是:
Exception in thread "main" com.fasterxml.jackson.core.JsonParseException: Invalid numeric value: Leading zeroes not allowed
at [Source: (String)"{"name": "Test", "fooId": 0001234567, "barId": 0003456789}"; line: 1, column: 28]
可以通过 JsonParser.Feature.ALLOW_NUMERIC_LEADING_ZEROS
:
允许前导零
public class Main {
public static void main(String[] args) throws IOException {
ObjectMapper objectMapper = new ObjectMapper();
objectMapper.configure(JsonParser.Feature.ALLOW_NUMERIC_LEADING_ZEROS, true);
FooRequest fooRequest = objectMapper.readValue("{\"name\": \"Test\", \"fooId\": 0001234567, \"barId\": 0003456789}", FooRequest.class);
System.out.println(fooRequest.getBarId());
}
}
或在 spring 中通过 Spring 启动的 application.properties
:
spring.jackson.parser.allow-numeric-leading-zeros=true
那么第二个JSON就解析成功了
为什么它适用于第一个 JSON?
因为默认情况下 Jackson 的 MapperFeature.ALLOW_COERCION_OF_SCALARS
是打开的。
来自其 javadoc:
When feature is enabled, conversions from JSON String are allowed, as long as textual value matches (for example, String "true" is allowed as equivalent of JSON boolean token true
; or String "1.0" for double
).
because all these values are starting with 0?
事实证明,是的,但出于 稍微 不同的原因
这是 class 我们要映射传入请求
@Getter
@Setter
public class FooRequest {
@Size(max = 255, message = "{error.foo.name.size}")
private String name;
@Digits(integer = 15, fraction = 0, message = "{error.foo.fooId.size}")
private Long fooId;
@Digits(integer = 15, fraction = 0, message = "{error.foo.barId.size}")
private Long barId;
}
我已经像上面那样使用了javax.validation.constraints.*
。如果我们发送像
{
"name": "Test",
"fooId": "0001234567",
"barId": "0003456789"
}
然后它工作正常,我们能够将结果保存在数据库中,但是如果我们像这样发送它:
{
"name": "Test",
"fooId": 0001234567,
"barId": 0003456789
}
然后我们得到 400 Bad Request
。我不明白我在做什么错,我只是想确保用户发送长度在 1-15 之间的数字,并希望将其映射到 Long
变量。是因为 fraction
还是因为所有这些值都以 0 开头?
第二个 JSON 是 而不是 一个 valid json 因为前导零。
背景
Spring 使用 Jackson 库进行 JSON 交互。
如果您尝试解析第二个 JSON:
,则 Jackson 的ObjectMapper
默认会抛出异常
public class Main {
public static void main(String[] args) throws IOException {
ObjectMapper objectMapper = new ObjectMapper();
objectMapper.readValue("{\"name\": \"Test\", \"fooId\": 0001234567, \"barId\": 0003456789}", FooRequest.class);
}
}
例外情况是:
Exception in thread "main" com.fasterxml.jackson.core.JsonParseException: Invalid numeric value: Leading zeroes not allowed
at [Source: (String)"{"name": "Test", "fooId": 0001234567, "barId": 0003456789}"; line: 1, column: 28]
可以通过 JsonParser.Feature.ALLOW_NUMERIC_LEADING_ZEROS
:
public class Main {
public static void main(String[] args) throws IOException {
ObjectMapper objectMapper = new ObjectMapper();
objectMapper.configure(JsonParser.Feature.ALLOW_NUMERIC_LEADING_ZEROS, true);
FooRequest fooRequest = objectMapper.readValue("{\"name\": \"Test\", \"fooId\": 0001234567, \"barId\": 0003456789}", FooRequest.class);
System.out.println(fooRequest.getBarId());
}
}
或在 spring 中通过 Spring 启动的 application.properties
:
spring.jackson.parser.allow-numeric-leading-zeros=true
那么第二个JSON就解析成功了
为什么它适用于第一个 JSON?
因为默认情况下 Jackson 的 MapperFeature.ALLOW_COERCION_OF_SCALARS
是打开的。
来自其 javadoc:
When feature is enabled, conversions from JSON String are allowed, as long as textual value matches (for example, String "true" is allowed as equivalent of JSON boolean token
true
; or String "1.0" fordouble
).
because all these values are starting with 0?
事实证明,是的,但出于 稍微 不同的原因