[英]JSON parse error: Cannot deserialize value of type `java.time.LocalDateTime` from String
[英]HttpMessageNotReadableException: JSON parse error: Cannot deserialize value of type `int` from String
创建 REST API 时如何显示转换错误以及其他验证错误?
@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.