给定 Spring-Boot + Jackson 用于 JSON 序列化 + org.springframework.boot:spring-boot-starter-validation
(必须手动包含 Spring Boot >= 2.3.0)
使用内置插件
- 添加
@Validated
到您的控制器
@Valid @NotNull @RequestBody List<@Valid Pojo> pojoList
在您的控制器方法签名中使用
但是,这将在无效 bean 上引发javax.validation.ConstraintViolationException
错误,默认情况下映射到500 Internal Error
。因此,请确保您也有ControllerAdvice
这个!
使用包装器
列表包装器很好(即具有单个字段 type 的类List<E>
),但是从上面的响应中,您还必须更改 JSON({"list": []}
vs []
),这不是很好...
解决方案:
- 在包装器中,
@JsonValue
在包装的列表字段上使用注释
- 添加一个以列表为参数的构造函数,并用
@JsonCreator
- 在您的控制器方法中,使用
@Valid @RequestBody ListWrapper<Pojo> tokenBodies
这很有效,很优雅,不需要更多。org.springframework.web.bind.MethodArgumentNotValidException
此外,它会在无效的 bean 上抛出通常的问题。
包装器示例(java):
(有关Kotlin中的完整示例,请参阅https://stackoverflow.com/a/64060909)
public class ValidList<E> {
@JsonValue
@Valid
@NotNull
@Size(min = 1, message = "array body must contain at least one item.")
private List<E> values;
@JsonCreator
public ValidList(E... items) {
this.values = Arrays.asList(items);
}
public List<E> getValues() {
return values;
}
public void setValues(List<E> values) {
this.values = values;
}
}
public class SomePojo {
@Min(value = 1)
int id;
@Size(min = 2, max = 32)
String token;
// getters and setters
}
@RestController
public class SomeController {
@PostMapping("/pojos")
public ValidList<SomePojo> test(@Valid @RequestBody ValidList<SomePojo> pojos) {
return pojos;
}
}
提交确定:
curl -H "Content-Type: application/json" -X POST http://localhost:8080/pojos -d '[{"id": 11, "token": "something"}]'
[{"token" : "something", "id" : 11}]
提交空正文:
curl -H "Content-Type: application/json" -X POST http://localhost:8080/ns -d '[]'
{
"timestamp" : "2020-09-25T09:55:05.462+00:00",
"error" : "Bad Request",
"message" : "Validation failed for object='validList'. Error count: 1",
"exception" : "org.springframework.web.bind.MethodArgumentNotValidException",
"path" : "/pojos",
"status" : 400,
"trace": "org.springframework.web.bind.MethodArgumentNotValidException: Validation failed for argument [0] in public com.example.demo.ValidList<com.example.demo.SomePojo> com.example.demo.SomeController.test(com.example.demo.ValidList<com.example.demo.SomePojo>): [Field error in object 'validList' on field 'values': rejected value [[]]; codes [Size.validList.values,Size.values,Size. [...]"
}
提交无效项目:
curl -H "Content-Type: application/json" -X POST http://localhost:8080/ns -d '[{"id": -11, "token": ""}]'
{
"timestamp" : "2020-09-25T09:53:56.226+00:00",
"error" : "Bad Request",
"message" : "Validation failed for object='validList'. Error count: 2",
"exception" : "org.springframework.web.bind.MethodArgumentNotValidException",
"path" : "/pojos",
"status" : 400,
"trace": "org.springframework.web.bind.MethodArgumentNotValidException: Validation failed for argument [0] in public com.example.demo.ValidList<com.example.demo.SomePojo> com.example.demo.SomeController.test(com.example.demo.ValidList<com.example.demo.SomePojo>) with 2 errors: [Field error in object 'validList' on field 'values[0].id': rejected value [-11]; co [...]"
}