Spring Boot验证在整数字段中接受浮点值。

huangapple go评论98阅读模式
英文:

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?

{&quot;score&quot;: 10.234234}

Spring Boot version: 2.0.3.RELEASE

答案1

得分: 1

我试图调试Spring Boot的验证类以找出发生了什么事情,但在查看@M.Denium的评论后,我搜索了Jackson的问题,并找到了一个相关的SO条目。

https://stackoverflow.com/questions/25076030/java-jackson-prevent-float-to-int-conversion-when-deserializing

我使用了@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.

https://stackoverflow.com/questions/25076030/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);

答案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.

huangapple
  • 本文由 发表于 2020年1月6日 22:09:54
  • 转载请务必保留本文链接:https://go.coder-hub.com/59613586.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定