[SPRING] Controller 메소드의 Collection에 바인딩 된 RequestBody 매개 변수에 대한 Spring 유효성 검사
SPRINGController 메소드의 Collection에 바인딩 된 RequestBody 매개 변수에 대한 Spring 유효성 검사
나는 가지고있다
엔티티 :
package org.ibp.soq;
public class MyEntity {
private String field1;
private String field2;
//..getters and setters
}
엔티티에 대한 검사기 :
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);
}
}
과
대량 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);
}
}
다음 요청 본문으로이 자원에 PUT 요청을 할 때 :
[
{
"field1": "AA",
"field2": "11"
},
{
"field1": "BB",
"field2": "22"
}
]
내가 얻는 오류는 다음과 같습니다.
"Invalid target for Validator [org.ibp.soq.MyEntityValidator@4eab617e]: [org.ibp.soq.MyEntity@21cebf1c, org.ibp.soq.MyEntity@c64d89b]"
이것이 MyEntityValidator가 MyEntity 유효성 검사를 "지원"하고 ArrayList
요청 본문에 단일 MyEntity 객체가 있고 @RequestBody @Valid MyEntity myEntity 매개 변수가있는 해당 컨트롤러 메소드가 있으면 MyEntityValidator가 완벽하게 작동합니다.
MyEntity의 콜렉션 유효성 검증을 지원하기 위해 유효성 검사기 설정을 어떻게 확장 할 수 있습니까?
해결법
-
==============================
1.해결책은 Collection에 대한 사용자 정의 검사기를 작성하고 WebDataBinders에 해당 Validator를 등록하는 @ControllerAdvice를 작성하는 것입니다.
해결책은 Collection에 대한 사용자 정의 검사기를 작성하고 WebDataBinders에 해당 Validator를 등록하는 @ControllerAdvice를 작성하는 것입니다.
검사기 :
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); } } }
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)); } }
-
==============================
2.짐작할 수 있듯이 스프링 밸리데이션을 사용하여이를 달성 할 수는 없습니다. Spring 유효성 검사는 객체 유효성 검사와 달리 Bean 유효성 검사 (JSR 303/349)를 구현합니다. 불행히도 컬렉션은 Java Bean이 아닙니다. 두 가지 옵션이 있습니다.
짐작할 수 있듯이 스프링 밸리데이션을 사용하여이를 달성 할 수는 없습니다. Spring 유효성 검사는 객체 유효성 검사와 달리 Bean 유효성 검사 (JSR 303/349)를 구현합니다. 불행히도 컬렉션은 Java Bean이 아닙니다. 두 가지 옵션이 있습니다.
-
==============================
3.실제로 이것은 Spring Validation과 JSR303을 사용하여 얻을 수 있습니다.
실제로 이것은 Spring Validation과 JSR303을 사용하여 얻을 수 있습니다.
from https://stackoverflow.com/questions/34011892/spring-validation-for-requestbody-parameters-bound-to-collections-in-controller by cc-by-sa and MIT license
'SPRING' 카테고리의 다른 글
[SPRING] 다중 모듈 프로젝트에서 Spring 부트 구성 요소 스캔 문제 (0) | 2019.01.22 |
---|---|
[SPRING] Spring에서 같은 키를 가진 여러 속성을 읽는 방법? (0) | 2019.01.22 |
[SPRING] Spring Security 3 용 AuthenticationSuccessHandler 예제 (0) | 2019.01.22 |
[SPRING] 어노테이션으로 bean 정의 상속? (0) | 2019.01.22 |
[SPRING] org.json.JSONObject 클래스 용의 직렬자를 발견하지 못해, BeanSerializer를 작성하는 프로퍼티가 발견되지 않았다 (0) | 2019.01.22 |