챕터 8: 예외 처리
8.1 스프링부트 예외 처리 전략
8.1.1 예외 처리의 필요성
예외 처리는 소프트웨어 개발에서 필수적인 부분으로, 예상치 못한 오류가 발생했을 때 시스템의 안정성을 유지하고 사용자에게 적절한 피드백을 제공하기 위해 필요합니다. 예외 처리는 프로그램이 오류 상황에서도 중단되지 않고 정상적으로 동작할 수 있도록 도와줍니다.
8.1.2 글로벌 예외 처리 전략
스프링부트는 글로벌 예외 처리 메커니즘을 제공하여 애플리케이션 전반에 걸쳐 일관된 예외 처리를 구현할 수 있습니다. 이는 예외가 발생했을 때 이를 일관되게 처리하고, 적절한 응답을 제공하여 사용자 경험을 개선합니다.
8.2 @ExceptionHandler와 @ControllerAdvice
8.2.1 @ExceptionHandler 사용법
@ExceptionHandler 어노테이션은 특정 컨트롤러에서 발생하는 예외를 처리하는 데 사용됩니다. 이를 통해 예외가 발생했을 때 특정 메서드에서 이를 처리할 수 있습니다.
package com.example.demo;
import org.springframework.http.HttpStatus;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.ResponseStatus;
import org.springframework.web.bind.annotation.RestController;
// 사용자 정의 예외 클래스
class CustomException extends RuntimeException {
public CustomException(String message) {
super(message);
}
}
// @RestController 어노테이션을 사용하여 이 클래스를 RESTful 웹 컨트롤러로 정의
@RestController
public class ExceptionHandlerController {
// @GetMapping을 사용하여 HTTP GET 요청을 매핑
@GetMapping("/triggerException")
public String triggerException() {
// 사용자 정의 예외를 발생시킴
throw new CustomException("Custom exception occurred!");
}
// @ExceptionHandler를 사용하여 CustomException을 처리
@ExceptionHandler(CustomException.class)
@ResponseStatus(HttpStatus.BAD_REQUEST)
public String handleCustomException(CustomException ex) {
// 예외 메시지를 응답으로 반환
return ex.getMessage();
}
}
위의 예제에서 @ExceptionHandler
어노테이션은 특정 예외를 처리하는 메서드를 정의합니다. triggerException
메서드는 사용자 정의 예외를 발생시키며, handleCustomException
메서드는 이를 처리하고 예외 메시지를 반환합니다.
8.2.2 @ControllerAdvice 사용법
@ControllerAdvice 어노테이션은 전역 예외 처리 메커니즘을 제공하여 모든 컨트롤러에 적용할 수 있는 예외 처리를 정의합니다. 이를 통해 애플리케이션 전반에 걸쳐 일관된 예외 처리를 구현할 수 있습니다.
package com.example.demo;
import org.springframework.http.HttpStatus;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseStatus;
// @ControllerAdvice 어노테이션을 사용하여 전역 예외 처리 클래스를 정의
@ControllerAdvice
public class GlobalExceptionHandler {
// @ExceptionHandler를 사용하여 CustomException을 처리
@ExceptionHandler(CustomException.class)
@ResponseStatus(HttpStatus.BAD_REQUEST)
public String handleCustomException(CustomException ex) {
// 예외 메시지를 응답으로 반환
return ex.getMessage();
}
// @ExceptionHandler를 사용하여 다른 예외를 처리
@ExceptionHandler(Exception.class)
@ResponseStatus(HttpStatus.INTERNAL_SERVER_ERROR)
public String handleGeneralException(Exception ex) {
// 예외 메시지를 응답으로 반환
return "An error occurred: " + ex.getMessage();
}
}
위의 예제에서 @ControllerAdvice
어노테이션은 전역 예외 처리 클래스를 정의합니다. GlobalExceptionHandler
클래스는 모든 컨트롤러에 적용될 예외 처리를 정의하며, handleCustomException
과 handleGeneralException
메서드는 각각 특정 예외와 일반 예외를 처리합니다.
8.3 커스텀 예외 클래스 작성
8.3.1 사용자 정의 예외 클래스 작성
사용자 정의 예외 클래스는 특정 조건에서 발생하는 예외를 처리하기 위해 작성할 수 있습니다. 이를 통해 보다 명확하게 예외 상황을 정의하고 처리할 수 있습니다.
package com.example.demo;
// 사용자 정의 예외 클래스
public class ResourceNotFoundException extends RuntimeException {
public ResourceNotFoundException(String message) {
super(message);
}
}
8.3.2 예외 메시지 설정
예외 메시지는 사용자 정의 예외 클래스의 생성자를 통해 설정할 수 있습니다. 이를 통해 예외가 발생했을 때 보다 구체적인 정보를 제공할 수 있습니다.
package com.example.demo;
// 사용자 정의 예외 클래스
public class ResourceNotFoundException extends RuntimeException {
private String resourceName;
private String fieldName;
private Object fieldValue;
public ResourceNotFoundException(String resourceName, String fieldName, Object fieldValue) {
super(String.format("%s not found with %s : '%s'", resourceName, fieldName, fieldValue));
this.resourceName = resourceName;
this.fieldName = fieldName;
this.fieldValue = fieldValue;
}
// Getter 메서드
public String getResourceName() {
return resourceName;
}
public String getFieldName() {
return fieldName;
}
public Object getFieldValue() {
return fieldValue;
}
}
위의 예제에서 사용자 정의 예외 클래스는 특정 리소스를 찾지 못했을 때 발생합니다. 예외 메시지는 리소스 이름, 필드 이름 및 필드 값을 포함하여 예외 상황을 보다 명확하게 설명합니다.
8.4 예외 메시지 국제화
8.4.1 메시지 소스 설정
스프링부트에서 예외 메시지의 국제화를 위해 메시지 소스를 설정할 수 있습니다. 이를 통해 여러 언어로 예외 메시지를 제공할 수 있습니다.
# application.properties
spring.messages.basename=messages
package com.example.demo;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.support.ResourceBundleMessageSource;
// 메시지 소스 설정
@Configuration
public class MessageSourceConfig {
@Bean
public ResourceBundleMessageSource messageSource() {
ResourceBundleMessageSource messageSource = new ResourceBundleMessageSource();
messageSource.setBasename("messages");
messageSource.setDefaultEncoding("UTF-8");
return messageSource;
}
}
8.4.2 다국어 지원 예외 메시지 작성
다국어 지원을 위해 각 언어별 메시지 파일을 작성할 수 있습니다. 이는 여러 언어로 된 사용자에게 적절한 예외 메시지를 제공하는 데 유용합니다.
# messages.properties
resource.not.found=Resource not found
# messages_ko.properties
resource.not.found=리소스를 찾을 수 없습니다
package com.example.demo;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.MessageSource;
import org.springframework.http.HttpStatus;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestHeader;
import org.springframework.web.bind.annotation.ResponseStatus;
import org.springframework.web.bind.annotation.RestController;
import java.util.Locale;
// @RestController 어노테이션을 사용하여 이 클래스를 RESTful 웹 컨트롤러로 정의
@RestController
public class LocalizationController {
@Autowired
private MessageSource messageSource;
// @GetMapping을 사용하여 HTTP GET 요청을 매핑
@GetMapping("/localizationTest")
public String localizationTest(@RequestHeader(name = "Accept-Language", required = false) Locale locale) {
// 요청된 언어에 맞는 예외 메시지를 반환
return messageSource.getMessage("resource.not.found", null, locale);
}
// @ExceptionHandler를 사용하여 ResourceNotFoundException을 처리
@ExceptionHandler(ResourceNotFoundException.class)
@ResponseStatus(HttpStatus.NOT_FOUND)
public String handleResourceNotFoundException(ResourceNotFoundException ex, Locale locale) {
// 요청된 언어에 맞는 예외 메시지를 반환
return messageSource.getMessage("resource.not.found", null, locale);
}
}
위의 예제에서 MessageSource
를 사용하여 국제화된 예외 메시지를 반환합니다. localizationTest
메서드는 요청 헤더에서 언어 정보를 받아서 해당 언어에 맞는 메시지를 반환합니다. handleResourceNotFoundException
메서드는 예외가 발생했을 때 적절한 언어로 메시지를 반환합니다.
'IT 강좌(IT Lectures) > SpringBoot' 카테고리의 다른 글
10강. Spring Boot DevTools (3) | 2024.07.23 |
---|---|
9강. Spring Boot Actuator (0) | 2024.07.22 |
7강. 데이터 접근 (0) | 2024.07.18 |
6강. 컨트롤러(Controller)와 라우팅(Routing) (0) | 2024.07.09 |
5강. 의존성 주입 (DI)와 빈 관리 (0) | 2024.06.27 |