본문 바로가기
Programming/Java_Spring

List에 속한 Class의 Validation.

by 곰네Zip 2022. 9. 29.

데이터의 유효성을 검증하기 위한 @Valid애노테이션을 사용할 수 있다.

 

관련된 내용은 여기.

https://gomnezip.tistory.com/421?category=943736 

 

@Valid시 Data Validation시 예외처리 남기기

@Valid 애노테이션을 사용하면, 전달받는 객체에 대해 검증을 처리할 수 있다. 그리고 BindingResult를 통해서 처리하든, 아니면 바로 BindException을 발생시켜버리든 가능하다. 근데, Exception이 발생한

gomnezip.tistory.com

 

근데 다음과 같은 경우에는 내가 MyDTO에 정의한 Validation이 안되더라..

@Getter
@Setter
public class MyDTO{
	@NotEmpty
    private String myName;
}

@Controller
public class MyController{
	@RequestMapping(value = {"/myTest"})
    public @ResponseBody Object myTest(@RequestBody @Valid List<MyDTO> dtoList){
    }
}

 이유는.. 저 List 자체가 유효한지 안한지 Validation을 수행하는 것..

 

 그러면, 저 MyDTO List중에 누가 이상한 녀석인지 검증할 방법이 없는건가???

아니.. 있더라. (그럼 그렇지... 그렇게 허술할리가..)

 애노테이션이 좀 바뀌어야한다. MyDTO는 그대로 유지하면 되고, 컨트롤러에서만 변경하자.

@Validated
@Controller
public class MyController{
	@RequestMapping(value={"/myTest"})
    public @ResponseBody Object myTest(@RequestBody
                                       @NotEmpty(message = "list is empty!")
                                       List<@Valid MyDTO> list){
       ...
    }
}

 컨트롤러에게 @Validated 애노테이션을 붙여주고, @Valid List<MyDTO>를 List<@Valid MyDTO>로 변경해준다.

@NotEmpty는 List가 비어있는 경우 Validation Fail을 발생시키고자 저렇게 붙여보았다. (List자체에 대한 Validation은 저기에 붙이면 된다.)

 

 이러면 Validation에 실패하면 Exception을 던져준다.

이전에 포스팅을 참고하면, @Valid 애노테이션이 붙은 Item은 org.springframework.validation.BindException이 발생했지만, List안에 속한 Item의 Validation실패는 javax.validation.ValidationException이 발생한다.

 Exception을 받아와서 처리할 때에는.. 저 exception에 대한 핸들러를 추가할것.

 근데, BindException과 ValidationException은 데이터 형식이 다르다. 나는 Target과 메시지를 뽑아내기위해 다음과 같이 처리했음.

public @ResponseBody Object handleValdiationException(javax.validation.ValidationException e){
	if( e.getClass().equals(ConstraintViolationException.class)){
    	Set<ConstraintViolation<?>> exceptions = 
        	((ConstraintViolationException)e).getConstraintViolations();
        for(ConstraintViolation<?> ex : exceptions){
        	String targetName = "";
        	for(Path.Node node : ex.getPropertyPath){
            	if( node.getKind().equals(ElementKind.PROPERTY)){
                	targetName = node.getName();
                }
            }
            String message = ex.getMessage();
        }
    }
}

ex.getLeafBean이 현재 문제를 일으킨 녀석을 반환하는듯.. 근데 이 녀석은 List에서 오류난 항목이 두개이면 두개를 모두 반환한다. 

 

참고로.. @Valid와 @Validated를 같이 붙였을 때, 실행 시 Bean에서 오류를 뿜어낼 때가 있다. mvcValidator와 다른 validator (나의 경우 localValidator)가 둘 다 있다고.. 이때에는 한쪽을 비활성화 하거나, 아니면 @Primary를 붙여서 누구를 우선할지 지정해주면 됨.

반응형

댓글