给定 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!
使用包装器
列表包装器很好(即,具有List<E> 类型的单个字段的类),但是从上面的响应中,您还必须更改 JSON({"list": []} 与 []),这不好看……
解决方案:
- 在包装器中,在包装后的列表字段上使用
@JsonValue注解
- 添加一个以列表为参数的构造函数,并用
@JsonCreator注释它
- 在你的控制器方法中,使用
@Valid @RequestBody ListWrapper<Pojo> tokenBodies
这很有效,很优雅,并且不需要更多。此外,它会在无效的 bean 上抛出通常的org.springframework.web.bind.MethodArgumentNotValidException。
包装器示例 (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 [...]"
}