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?

事实证明,是的,但出于 稍微 不同的原因