This is class against which we are going to map the incoming request
@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;
}
I have used javax.validation.constraints.*
like above. If we send request like
{
"name": "Test",
"fooId": "0001234567",
"barId": "0003456789"
}
Then It works fine and we are able to save the results in the database but if we send it like:
{
"name": "Test",
"fooId": 0001234567,
"barId": 0003456789
}
Then we are getting 400 Bad Request
. I am not getting it what wrong am I doing, I just want to ensure that user sends digits, having length between 1-15 and wants to map it against the Long
variable. Is it because of fraction
or because all these values are starting with 0?
The second JSON is not a valid json because of the leading zeroes.
Spring uses Jackson library for JSON interactions.
The Jackson's ObjectMapper
by default throws if you try to parse the second JSON:
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);
}
}
The exception is:
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]
One can allow leading zeroes via the 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());
}
}
Or in spring via the Spring Boot's application.properties
:
spring.jackson.parser.allow-numeric-leading-zeros=true
then, the second JSON will be parsed successfully.
Because by default Jackson's MapperFeature.ALLOW_COERCION_OF_SCALARS
is turned on.
From its 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?
So it turns out that, yes, but for a slightly different reason