Spring

@ControllerAdvice, @ExceptionHanlder

keepgoing 2023. 3. 18. 17:36

 

ExceptionHandler 어노테이션은 Controller와 RestController 클래스에서 발생한 예외를 별도의 메소드를 custom으로 생성해서 처리해준다.

 

쉽게 설명하자면 Controller 클래스에서 발생하는 예외 처리는 필드가 많아질 수록 복잡해진다. 

BindingResult result

if(result.hasError()){
	List<FieldError> fieldErros = result.getFieldErrors();
    
    FieldError fieldError = fieldErrors.get(0);
    
    String fieldName = fieldError.getField();
    String ErrorMessage = fieldError.getDefaultMessage();
    
    Map<String, String> error = new HashMap<>();
    
   	error.put(fieldName, fieldMessage);
}

 

위와 같은 코드를 모든 메서드에서 선언해주는건 무리가 있다.

 

이런 예외 처리 반복같은 중노동을 방지해주는 기능을 ExceptionHandler에서 제공해준다.

 

ExceptionHandelr(value)에 들어가는 value 값은 어떤 예외를 잡을 것인지 특정 지어줄 수 있다. 

만약 value 값을 선언하지 않는다면 모든 에러를 다 잡을 것이다.

 

    @ExceptionHandler(MethodArgumentNotValidException.class)

@ControllerAdvice에 특정 컨트롤러 클래스를 지정하지 않으면 @Controller가 선언된 모든 클래스의 예외처리를 맡아준다. 

@ControllerAdvice 안에 @ExceptionHandler가 포함되어 있다.

@ControllerAdvice
@Slf4j
public class ExceptionController {
    @ResponseStatus(HttpStatus.BAD_REQUEST)
    @ExceptionHandler(MethodArgumentNotValidException.class)
    @ResponseBody // json 형태로 예외 처리를 해주고 싶기 때문에 추가.(삭제 시 ViewResolver 오류)
    public ErrorResponse inValidRequestHandler(MethodArgumentNotValidException e){

        ErrorResponse response =  ErrorResponse.builder()
                .code("400")
                .message("잘못된 요청입니다.")
                .build();

        for(FieldError fieldError : e.getFieldErrors()){
            response.addValidation(fieldError.getField(), fieldError.getDefaultMessage());
        }

        return response;
    }

}

위 코드는 @ControllerAdvice를 적용한 클래스