Reputation: 10633
I'm trying to implement a POST service with request validation.
My Controller
method looks something like below
public void updateScore(@Valid ScoreRequest)
ScoreRequest
looks like below
import javax.validation.constraints.*;
import lombok.Data;
@Data
public class ScoreRequest {
@Min(0)
@Max(100)
@Digits(fraction = 0, integer = 3)
private Integer score;
...
}
It all works fine till I pass integer values for score, however If I pass fraction part as well, request goes through and Spring somehow truncates the fraction and uses the integer part in the request.
I was expecting it to throw a validation error since datatype of score doesn't match.
It works with followling request, and uses 10 as the score value in the request object. I'm expecting it to throw an error, what am I doing wrong?
{"score": 10.234234}
Spring Boot version: 2.0.3.RELEASE
Upvotes: 1
Views: 8738
Reputation: 10633
I was trying to debug Spring Boot's validation classes to find what was happening, but after looking at the comment by @M.Denium I searched for Jackson issues and found a related SO entry.
Java Jackson - prevent float to int conversion when deserializing
I'm using answer by @Jichao Zhang
, however Just to confirm answer by @Eduardo Sanchez-Ros
works as well. This is what works for me.
ObjectMapper.configure(DESERIALIZATION_FEATURE.ACCEPT_FLOAT_AS_INT, false);
Upvotes: 1
Reputation: 3158
If you closely look at the definition of the @digits
annotation,
@Target({ METHOD, FIELD, ANNOTATION_TYPE, CONSTRUCTOR, PARAMETER })
So this annotation can be applied to methods also.
If you read the docs, it says this annotation can be applied to the following types
the integer
field of the annotation checks for the number of integral digits while the fraction
field of the annotation checks for the number of fractional digits.
Since, you declared your field to be an Integer value. It casts the value to an integer and truncates the fractional part.
This does not fail validations as both the fields satisfy the validation.
This annotation is ideally to be only used with BigDecimal
type.
Upvotes: 0
Reputation: 1672
Don't use this annotation: @Digits(fraction = 0, integer = 3
with Integer since it is useless to set fractions for Integer
.
Why don't you do:
@Min(0)
@Max(100)
@Digits(fraction = 0, integer = 3)
private BigDecimal score;
Upvotes: 0