繁体   English   中英

HttpMessageNotReadableException:JSON 解析错误:无法从字符串反序列化“int”类型的值

[英]HttpMessageNotReadableException: JSON parse error: Cannot deserialize value of type `int` from String

创建 REST API 时如何显示转换错误以及其他验证错误?

  • Spring 开机
  • Spring MVC
  • REST Controller
@Data
@AllArgsConstructor
class DTO
{
    @NotNull
    @Min(1)
    private Integer id;
}

@RestController
class ExampleController
{
    @PostMapping("/")
    public void createEndpoint(@Valid @RequestBody DTO dto) {
        return "{\"message\": \"OK\"}";
    }
}

当我向这个端点发出请求时,

POST /
{
    "id: "abrakadabra"
}

我想得到这样的东西

{
    "errors": {
        "id": [
            { code: "invalid_format", message: "Field must contain only digits" }
        ]
    }
}

我实际上得到了什么?

Resolved [org.springframework.http.converter.HttpMessageNotReadableException: JSON parse error: Cannot deserialize value of type `int` from String "abrakadabra": not a valid `int` value;
nested exception is com.fasterxml.jackson.databind.exc.InvalidFormatException: Cannot deserialize value of type `int` from String "abrakadabra": not a valid `int` value
at [Source: (PushbackInputStream); line: 2, column: 24] (through reference chain: com.mylid.back.dtos.CreateCompanyDto["pricing_plan_id"])]

我知道我可以创建自定义注释进行验证。 但问题是该过程没有达到验证。 它在反序列化步骤中失败。

[可能的方式]

有一个肮脏的技巧,将 DTO 中的 Integer 类型更改为字符串。 创建自定义注释以检查字符串是否仅包含数字。 然后在Entity中手动map这个String从DTO到Integer。 然后保存到数据库。

还有什么其他方法可以解决这个问题? 很奇怪,在 Google 和 StackOverFlow 上有一些针对这个特定问题的主题。 在几乎每一页上,接受的答案都是“这不是我们的问题,API 客户端应该传递整数”。

在 PHP 中,我们可以使用“整数”验证器轻松完成,几乎每个框架都有它,如果我通过“abracadabra”而不是“1”,它不会阻止其他字段的验证。

实现自定义类型怎么样?

例如(下面的代码是废话,缺少 null 处理等等 - 只是想向您展示这个想法)

public class DTOId {
    final Integer value;

    private DTOId(String value) {
        Assert.hasText(value, "Value for DTOId should not not be null or empty!");
        // Validation that it is a integer, min value and so on
        this.value = Integer.valueOf(value);
    }

    @JsonCreator
    public static DTOId of(final String value) {
        return new DTOId(value);
    }

    @JsonValue
    public String toString() {
        return value.toString();
    }
}

然后你可以使用

@Data
@AllArgsConstructor
class DTO
{
    @NotNull
    private DTOId id;
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM