英文:
Spring Boot validation takes float value in integer field
问题
我正在尝试实现一个带有请求验证的POST服务。
我的Controller
方法看起来像下面这样:
public void updateScore(@Valid ScoreRequest)
ScoreRequest
看起来像下面这样:
import javax.validation.constraints.*;
import lombok.Data;
@Data
public class ScoreRequest {
@Min(0)
@Max(100)
@Digits(fraction = 0, integer = 3)
private Integer score;
...
}
一切都很正常,直到我传递整数值作为分数,但是如果我同时传递小数部分,请求会继续,Spring会在请求中截断小数部分并使用整数部分。
我预期它会抛出一个验证错误,因为分数的数据类型不匹配。
它可以使用以下请求,使用10作为请求对象中的分数值。我预期它会抛出错误,我做错了什么?
{"score": 10.234234}
Spring Boot版本:2.0.3.RELEASE
英文:
I'm trying to implement a POST service with request validation.
My Controller
method looks something like below
<!-- language: lang-java -->
public void updateScore(@Valid ScoreRequest)
ScoreRequest
looks like below
<!-- language: lang-java -->
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
答案1
得分: 1
我试图调试Spring Boot的验证类以找出发生了什么事情,但在查看@M.Denium的评论后,我搜索了Jackson的问题,并找到了一个相关的SO条目。
我使用了@Jichao Zhang
的答案,但只是确认@Eduardo Sanchez-Ros
的答案也有效。这对我有效。
ObjectMapper.configure(DESERIALIZATION_FEATURE.ACCEPT_FLOAT_AS_INT, false);
英文:
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.
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);
答案2
得分: 0
不要在整数上使用此注释:@Digits(fraction = 0, integer = 3)
,因为为 Integer
设置小数部分是没有意义的。
为什么不这样做:
@Min(0)
@Max(100)
@Digits(fraction = 0, integer = 3)
private BigDecimal score;
英文:
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;
答案3
得分: 0
如果您仔细查看@digits
注解的定义,
@Target({ METHOD, FIELD, ANNOTATION_TYPE, CONSTRUCTOR, PARAMETER })
因此,此注解也可以应用于方法。 <br>
如果您阅读文档,它说此注解可应用于以下类型
- BigDecimal
- BigInteger
- CharSequence
- byte (或 Byte)
- short (或 Short)
- int (或 Integer)
- long (或 Long)
注解的integer
字段检查整数位数,而注解的fraction
字段检查小数位数。
<br><br>
由于您声明您的字段为Integer值。它将值强制转换为整数并截断小数部分。<br>
这不会导致验证失败,因为两个字段都满足验证条件。
<br><br>
此注解理想情况下仅应与BigDecimal
类型一起使用。
英文:
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. <br>
If you read the docs, it says this annotation can be applied to the following types
- BigDecimal
- BigInteger
- CharSequence
- byte (or Byte)
- short (or Short)
- int (or Integer)
- long (or Long)
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.
<br><br>
Since, you declared your field to be an Integer value. It casts the value to an integer and truncates the fractional part.<br>
This does not fail validations as both the fields satisfy the validation.
<br><br>
This annotation is ideally to be only used with BigDecimal
type.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论