본문 바로가기
Spring

1) Spring Boot Validation - Annotation 메세지 & Exception 에러 발생시 동작 설명

by Gil Granger 2019. 6. 14.

 

 

@Vaild, @NotBlank  annotation을 이용한 Server Validation 사용 예제

Controller Dto Parameter
DTO Class

응답 에러 메세지 @NotNull 예제:)

{
  "timestamp":"2019-06-25T05:34:07.173+0000",
  "status":400,
  "error":"Bad Request",
  "errors":[
	{
        "codes":[
          "NotNull.agDto.pe",
          "NotNull.agype",
          "NotNull"
        ],
        "arguments":[
              {
              "codes":[ " ..." ],
              "arguments":null,
              "defaultMessage":"...",
              "code":"..."
              }
         ],
        "defaultMessage":"반드시 값이 있어야 합니다.",
        "objectName":"...",
        "field":"..",
        "rejectedValue":null,
        "bindingFailure":false,
        "code":"NotNull"
	}
  ],
  "message":"Validation failed for object='...'. Error count: 1",
  "path":"/api/../.."
}

이와 같은 방법으로 Exception을 발생시킬 경우 에러 응답메세지를 설정하여 별다른 설정없이 간단하게 Server Validation을 줄 수가 있다.

 


Validation 에러 발생시 동작 설명

 

 

Validation Annotaion을 사용하였을때 조건에 부합되지 않은 경우 Excepiton이 어떻게 동작하는지 알아보도록 한다. 

request content type에 따라 Exception 처리 로직이 다르다는것을 확인 할 수 있었다.

 

Form Data Reqeust의 경우

ModelAttributeMethodProcessor

AJAX(XMLHttpRequest) 의 경우

RequestResponseBodyMethodProcessor

 

위와 같이 이렇게 request 에서 유효성 검사를 하여 @NotBalnk 등의 Anotation 조건이 충족되지 않을시 Exception을 throw하게 된다.

 

이제 Exception을 만나게될때 내용을 정리해본다면 (환경:  스프링부트 내장 서버 톰캣)

 

@ControllerAdvice, @RestControllerAdvice와 같은 방법으로 별도로 에러처리를 하지 않았다면 내장된 톰캣에서는 전반적인 에러처리를 ErrorController 에 위임하여 처리하게 된다. 

 

이후 동작원리와 코드에 대해서는 아래와 같다. 

 

 

StandardHostValve
StandardHostValve

StandardHostValve클래스에서 이와 같이 /error 리다이렉트하게 된다.

DispatcherServlet

request를 확인하고 error html 형식. 또는 JSON 형태의 Response을 줄것인지 handler를 결정한다. (mappedHandler)

 

BasicErrorController

Exception이 발생하여 StandardHostValve클래스에서 이와 같이 /error 리다이렉트하게 된다.

쭉 로직을 따라가보면
error html 형식으로 응답을 줄경우 classpath의 view resource path의 있는 html을 찾기 시작한다. 
(ex: 400에러의 경우 /error/{errorcode}  -> /error/4xx -> error.html)
custom 에러페이지를 찾을 수 없다면 하얀 톰캣 white label 페이지가 뜰것이다.

 

errorHtml, error method에서 getErrorAttributes호출로 데이터를 가져올 수 있는것을 볼 수 있는데, 우리가 이부분을 이용하여 에러응답을 줄때 Exception Class을 생성하여 Exception에 따라 응답 메세지 등을 삽입할 수 있다.
(Validtaion등에 사용)

 

DefaultErrorAttributes
DefaultErrorAttributes
DefaultErrorAttributes

에러 발생시 DefaultErrorAttributes 클래스에서 에러메세지를 삽입하는것을 볼 수 있다.

javax.validation.constraints 패키지에 있는 Validation Annotation을 사용하여 유효성(@valid) 검사를 하는 경우 기본적으로  DefaultErrorAttributes클래스에서 addErrorMessage 메소드를 사용하여 에러 Response를 담아준다.

자 그렇다면, ErrorAttributes를 통해 에러 발생시 원하는 메세지를 전달 할수 있도록 해보자. 

 


Custom Excetpion,  Response Error Message 설정 방법

예제) 

 

Spring Boot 2.1 버전 기준

Spring Boot 2.3 버전 이후

 

 

IdEmailDuplicationException 발생시 응답에러 메세지를 설정할수 있도록 한 예제이다.

특정한 상황에서 throw IdEmailDuplicationException을 하게 된다면 에러 Response를 줄때 erros key에 필드를 담아서 응답을 주게 될것이다. 

 

 

2) Validation Custom Annocation

https://granger.tistory.com/51

 

Spring Boot Custom Annotation Validation

Annotation을 만들어서 서버에 요청받았을때 유효성 검증을 하고 원하는 메세지를 줄 수 있도록 해보자. 다음은 Pattern Annocation 을 이용하여 원하는 패턴의 정규식만 검증하도록 만든 Annotation 이다. 이름..

granger.tistory.com


 

참조

https://supawer0728.github.io/2019/04/04/spring-error-handling/

https://www.baeldung.com/exception-handling-for-rest-with-spring

https://www.baeldung.com/global-error-handler-in-a-spring-rest-api

https://luvstudy.tistory.com/74

https://cheese10yun.github.io/spring-guide-exception/

댓글