java, spring

[Spring framework] Controller의 Exception 처리

isaac.kim 2021. 5. 29. 22:28
728x90
반응형

[Spring framework] Controller의 Exception 처리

 

스프링 MVC에선 예외 상황을 고려하여 Controller를 작성하려면 작업이 엄청나게 늘어날 수밖에 없습니다. 모든 메서드에 Exception을 추가하는 작업은 곧 중복되는 코드의 많은 양을 메서드가 추가될 때마다 써야 하는 것일 수도 있습니다.

다음과 같은 방법을 사용하여 예외 처리하는 코드의 중복을 최소화할 수 있는 방법이 있습니다.

 

1. @ExceptionHandler와 @ControllerAdvice를 이용한 처리

2. @ResponseEntity를 이용하는 예외 메시지 구성

 

오늘은 @ExceptionHandler와 @ControllerAdvice 어노테이션을 이용한 처리 방법에 대해 알아보겠습니다.

 

 

@ControllerAdvice를 이용하여 예외 처리하기

@ControllerAdvice는 AOP(Aspect-Oriented-Programming)를 이용하는 방식입니다. AOP에 대해 간단히 언급하자면 핵심적인 로직은 아니지만 프로그램에서 필요한 '공통적인 관심사(cross-concern)는 분리'하자는 개념입니다. Controller를 작성할 때는 메서드의 모든 예외사항을 전부 핸들링해야 한다면 중복적이고 많은 양의 코드를 작성해야 하지만, AOP 방식을 이용하면 공통적인 예외사항에 대해서는 별도로 @ControllerAdvice를 이용해서 분리하는 방식입니다.

 

com.project.exception 패키지를 추가하고, 그 아래 CommonExceptionAdvice 클래스를 생성합니다.

 

 

CommonExceptionAdvice 클래스

CommonExceptionAdvice는 @ControllerAdvice 어노테이션을 적용하지만 예외 처리를 목적으로 생성하는 클래스이므로 별도의 로직을 처리하지는 않습니다.

package com.project.exception;

import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;

import lombok.extern.log4j.Log4j;

@ControllerAdvice
@Log4j
public class CommonExceptionAdvice {

	@ExceptionHandler(Exception.class)
	public String except(Exception ex, Model model) {
	
		log.error("Exception ..." + ex.getMessage());
		model.addAttribute("exception", ex);
		log.error(model);
		
		return "error_page";
	}
	
}

CommonExceptionAdvice 클래스에는 @ControllerAdvice, @ExceptionHandler 이 두 어노테이션을 사용하고 있습니다. @ControllerAdvice는 해당 객체가 스프링의 컨트롤러에서 발생하는 예외를 처리하는 존재임을 명시하는 용도로 사용하고, @ExceptionHandler는 해당 메서드가 ( ) 들어가는 예외 타입을 처리한다는 것을 의미합니다.  @ExceptionHandler 어노테이션의 속성으로는 Exception 클래스 타입을 지정할 수 있습니다. 위와 같은 경우 Exception.class를 지정하였으므로 모든 예외에 대한 처리가 except( )만을 이용해서 처리할 수 있습니다.

 

JSP화면에서 구체적인 메시지를 보고 싶다면 Model을 이용해서 전달하는 것이 좋습니다. com.project.exception 패키지는 servlet-context.xml에서 인식하지 않기 때문에 <component-scan>을 이용해서 해당 패키지의 내용을 조사하도록 해야 합니다.

 

servlet-context.xml

 

작성한 except( ) 메서드 리턴 타입이 문자열이고, 반환 값이 "error_page" 이므로, '/src/main/webapp/WEB-INF/views/' 아래에 error_page.jsp 파일을 작성합니다.

error_page.jsp

예외 메시지를 확인하기 위해 고의적으로 url 요청 시 parameter 타입이 매치되지 않도록 넣어 호출해 볼 수 있습니다. 예를 들어 숫자 타입의 데이터를 입력해야 하는 데 문자를 넣거나, 파라미터를 누락한다던지 등.

 

테스트해보겠습니다.

int형 파라미터를 받아야 하는 상황에서 age의 파라미터 값을 문자열 xxx를 넣어 보냈더니 다음과 같은 에러 페이지가 나타나는 것을 확인할 수 있었습니다.

 

로그도 살펴보면, url 요청이 들어왔고, 타입이 미스매치되어 예외 처리하는 핸들러가 동작하고, 에러 페이지를 띄우는 것을 확인할 수 있습니다.

 

Java 설정을 이용하는 경우

ServletConfig 클래스에 'com.project.exception' 패키지를 인식해야 하므로, @ComponentScan의 인자 항목에 해당 패키지를 추가합니다.

 

 

오늘은 스프링에서 @ExceptionHandler와 @ControllerAdvice 어노테이션을 이용하여 예외 처리하는 방법에 대해 알아보았습니다.

 

 

 

참고서적 :코드로 배우는 스프링 웹 프로젝트

728x90
반응형