我有
实体:
package org.ibp.soq;
public class MyEntity {
private String field1;
private String field2;
//..getters and setters
}
Run Code Online (Sandbox Code Playgroud)
实体的验证者:
package org.ibp.soq;
import org.springframework.stereotype.Component;
import org.springframework.validation.Errors;
import org.springframework.validation.Validator;
@Component
public class MyEntityValidator implements Validator {
@Override
public boolean supports(Class<?> clazz) {
return MyEntity.class.equals(clazz);
}
@Override
public void validate(Object target, Errors errors) {
MyEntity myEntity = (MyEntity) target;
// Logic to validate my entity
System.out.print(myEntity);
}
}
Run Code Online (Sandbox Code Playgroud)
和
具有批量PUT方法的REST控制器:
package org.ibp.soq;
import java.util.List;
import javax.validation.Valid;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.WebDataBinder;
import org.springframework.web.bind.annotation.InitBinder;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;
@RestController
@RequestMapping("/myEntity")
public class MyEntityRestResource {
@Autowired
private MyEntityValidator myEntityValidator;
@InitBinder
protected void initBinder(final WebDataBinder binder) {
binder.addValidators(this.myEntityValidator);
}
@RequestMapping(method = RequestMethod.PUT)
public void bulkCreate(@RequestBody @Valid List<MyEntity> myEntities) {
// Logic to bulk create entities here.
System.out.print(myEntities);
}
}
Run Code Online (Sandbox Code Playgroud)
当我使用以下请求主体向此资源发出PUT请求时:
[
{
"field1": "AA",
"field2": "11"
},
{
"field1": "BB",
"field2": "22"
}
]
Run Code Online (Sandbox Code Playgroud)
我得到的错误是:
"Invalid target for Validator [org.ibp.soq.MyEntityValidator@4eab617e]: [org.ibp.soq.MyEntity@21cebf1c, org.ibp.soq.MyEntity@c64d89b]"
Run Code Online (Sandbox Code Playgroud)
我可以理解这是因为MyEntityValidator"支持"单一MyEntity验证,而不是验证ArrayList<MyEntity>.
MyEntityValidator如果我MyEntity在请求体中有单个对象和带@RequestBody @Valid MyEntity myEntity参数的相应控制器方法,那么效果很好.
我如何使用验证器设置,扩展以支持验证集合的验证MyEntity?
eru*_*uiz 16
该解决方案是创建一个自定义Validator的Collection和@ControllerAdvice是注册了Validator的WebDataBinders.
验证器:
import java.util.Collection;
import org.springframework.validation.Errors;
import org.springframework.validation.ValidationUtils;
import org.springframework.validation.Validator;
import org.springframework.validation.beanvalidation.LocalValidatorFactoryBean;
/**
* Spring {@link Validator} that iterates over the elements of a
* {@link Collection} and run the validation process for each of them
* individually.
*
* @author DISID CORPORATION S.L. (www.disid.com)
*/
public class CollectionValidator implements Validator {
private final Validator validator;
public CollectionValidator(LocalValidatorFactoryBean validatorFactory) {
this.validator = validatorFactory;
}
@Override
public boolean supports(Class<?> clazz) {
return Collection.class.isAssignableFrom(clazz);
}
/**
* Validate each element inside the supplied {@link Collection}.
*
* The supplied errors instance is used to report the validation errors.
*
* @param target the collection that is to be validated
* @param errors contextual state about the validation process
*/
@Override
@SuppressWarnings("rawtypes")
public void validate(Object target, Errors errors) {
Collection collection = (Collection) target;
for (Object object : collection) {
ValidationUtils.invokeValidator(validator, object, errors);
}
}
}
Run Code Online (Sandbox Code Playgroud)
ControllerAdvice:
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.validation.beanvalidation.LocalValidatorFactoryBean;
import org.springframework.web.bind.WebDataBinder;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.InitBinder;
/**
* Controller advice that adds the {@link CollectionValidator} to the
* {@link WebDataBinder}.
*
* @author DISID CORPORATION S.L. (www.disid.com)
*/
@ControllerAdvice
public class ValidatorAdvice {
@Autowired
protected LocalValidatorFactoryBean validator;
/**
* Adds the {@link CollectionValidator} to the supplied
* {@link WebDataBinder}
*
* @param binder web data binder.
*/
@InitBinder
public void initBinder(WebDataBinder binder) {
binder.addValidators(new CollectionValidator(validator));
}
}
Run Code Online (Sandbox Code Playgroud)
小智 1
正如您可能已经猜到的那样,这无法使用 Spring Validation 来实现。Spring Validation 实现了 Bean Validation(JSR 303/349),而不是对象验证。不幸的是,集合不是 Java Bean。你有两个选择
myEntityValidator. validate(targetObject, errors)。| 归档时间: |
|
| 查看次数: |
7430 次 |
| 最近记录: |