簡體   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