我正在尝试在Model类中的某些属性上使用@NotNull
注释,当我通过单个对象执行POST
调用而不是进行POST
调用时,它可以工作List
个对象
型号:DefaultModel.class
@Setter
@Getter
@NoArgsConstructor
@AllArgsConstructor
@Accessors(chain = true)
@ToString
public class DefaultModel {
@NotNull
private String name;
@NotNull
private Integer id;
}
控制器:HelloWorldController.java
@RequestMapping(value="/default", method=RequestMethod.POST)
public List<DefaultModel> m1(@RequestBody() @Valid List<DefaultModel> model) {
System.out.println(model);
return model;
}
List
个对象的输入有效载荷
[
{
"name":null,
"id":1
},
{
"name":null,
"id":""
},
{
"name":"",
"id":1
}
]
输出:
[DefaultModel(name=null, id=1), DefaultModel(name=null, id=null), DefaultModel(name=, id=1)]
我知道我们可以通过这种方式设置默认错误消息@NotNull(message="defaultmessage")
它还会引发MethodArgumentNotValidException
异常,我们可以采用以下方式处理
@ExceptionHandler(MethodArgumentNotValidException.class)
public List<String> handleValidationExceptions(MethodArgumentNotValidException ex)
我的问题是,是否仍然存在,以便我们可以覆盖方法并设置此默认值?并且如果List中的某些对象属性为null(在我的情况下正是)该怎么办,它将终止于中间还是忽略该对象?
答案 0 :(得分:0)
实际上,默认情况下,验证不适用于值得列表元素。
但是您可以为集合编写一个自定义验证器,并将其绑定到控制器的数据绑定器中。
@Controller
public class MyController {
private final LocalValidatorFactoryBean validator;
@Autowired
public MyController(LocalValidatorFactoryBean validator) {
this.validator = validator;
}
@InitBinder
public void initBinder(WebDataBinder binder) {
binder.addValidators(new CollectionValidator(validator));
}
}
class CollectionValidator implements Validator {
private final Validator validator;
CollectionValidator(LocalValidatorFactoryBean validatorFactory) {
this.validator = validatorFactory;
}
@Override
public boolean supports(Class<?> aClass) {
return Collection.class.isAssignableFrom(aClass);
}
@Override
public void validate(Object object, Errors errors) {
Collection collection = (Collection) object;
for (Object collectionValue : collection) {
ValidationUtils.invokeValidator(validator, collectionValue, errors);
}
}
}
或者您可以在带注释的@ControllerAdvice
类中进行相同的绑定,这将导致该绑定对所有控制器都可用。
已更新 控制器建议将是相同的逻辑,只是带有不同注释的类:
@ControllerAdvice
public class MyControllerAdvice {
private final LocalValidatorFactoryBean validator;
@Autowired
public MyController(LocalValidatorFactoryBean validator) {
this.validator = validator;
}
@InitBinder
public void initBinder(WebDataBinder binder) {
binder.addValidators(new CollectionValidator(validator));
}
}