如何在创建REST API时显示转换错误和其他验证错误
- 弹簧靴
- Spring MVC
- REST控制器
@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类型更改为String。创建自定义注释以检查字符串是否仅包含数字。然后手动将此字符串从DTO映射到Entity中的Integer。然后保存到数据库
还有什么其他方法可以解决这个问题?非常奇怪的是,谷歌和StackOverFlow上有一些关于这个特定问题的话题。在几乎每一页上,公认的答案都是";这不是我们的问题,API客户端应该传递整数;。
在PHP中,我们可以很容易地使用"integer"验证器进行验证,几乎每个框架都有它,并且如果我通过"integer验证",它不会阻止其他字段进行验证;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;
}