"일꾼이 일을 잘하려면 먼저 도구를 갈고 닦아야 한다." - 공자, 『논어』.
첫 장 > 프로그램 작성 > 스프링 부트의 예외 처리

스프링 부트의 예외 처리

2024-08-25에 게시됨
검색:273

Exception Handling in Spring Boot

예외 처리는 강력하고 사용자 친화적인 애플리케이션을 구축하는 데 중요한 부분입니다. Spring Boot에서는 애플리케이션이 안정적으로 유지되고 사용자에게 의미 있는 피드백을 제공할 수 있도록 다양한 방법으로 예외를 처리할 수 있습니다. 이 가이드에서는 사용자 지정 예외, 전역 예외 처리, 유효성 검사 오류 및 프로덕션 모범 사례를 포함하여 예외 처리에 대한 다양한 전략을 다룹니다.

1. 예외처리의 기본

예외는 프로그램의 정상적인 흐름을 방해하는 이벤트입니다. 다음과 같이 나눌 수 있습니다:

  • 검사된 예외: 컴파일 타임에 검사되는 예외입니다.
  • 검사되지 않은 예외(런타임 예외): 런타임 중에 발생하는 예외입니다.
  • 오류: OutOfMemoryError와 같이 애플리케이션이 처리해서는 안 되는 심각한 문제.

2. 사용자 정의 예외 클래스

사용자 정의 예외 클래스를 생성하면 애플리케이션의 특정 오류 조건을 처리하는 데 도움이 됩니다.

package com.example.SpringBootRefresher.exception;

public class DepartmentNotFoundException extends RuntimeException {
    public DepartmentNotFoundException(String message) {
        super(message);
    }
}

3. 컨트롤러의 예외 처리

@ExceptionHandler 주석:
컨트롤러 클래스에서 예외를 처리하는 메서드를 정의할 수 있습니다.

package com.example.SpringBootRefresher.controller;

import com.example.SpringBootRefresher.exception.DepartmentNotFoundException;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
public class DepartmentController {

    @GetMapping("/department")
    public String getDepartment() {
        // Simulate an exception
        throw new DepartmentNotFoundException("Department not found!");
    }

    @ExceptionHandler(DepartmentNotFoundException.class)
    public ResponseEntity handleDepartmentNotFoundException(DepartmentNotFoundException ex) {
        return new ResponseEntity(ex.getMessage(), HttpStatus.NOT_FOUND);
    }
}

4. @ControllerAdvice를 사용한 전역 예외 처리

전역적으로 예외를 처리하려면 @ControllerAdvice 및 중앙 집중식 예외 처리기를 사용할 수 있습니다.

package com.example.SpringBootRefresher.error;

import com.example.SpringBootRefresher.entity.ErrorMessage;
import com.example.SpringBootRefresher.exception.DepartmentNotFoundException;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseStatus;
import org.springframework.web.context.request.WebRequest;
import org.springframework.web.servlet.mvc.method.annotation.ResponseEntityExceptionHandler;

@ControllerAdvice
@ResponseStatus
public class CustomResponseEntityExceptionHandler extends ResponseEntityExceptionHandler {

    @ExceptionHandler(DepartmentNotFoundException.class)
    public ResponseEntity handleDepartmentNotFoundException(DepartmentNotFoundException exception, WebRequest request) {
        ErrorMessage message = new ErrorMessage(
                HttpStatus.NOT_FOUND.value(),
                exception.getMessage(),
                request.getDescription(false)
        );

        return ResponseEntity.status(HttpStatus.NOT_FOUND)
                .body(message);
    }

    @ExceptionHandler(Exception.class)
    public ResponseEntity handleGlobalException(Exception exception, WebRequest request) {
        ErrorMessage message = new ErrorMessage(
                HttpStatus.INTERNAL_SERVER_ERROR.value(),
                exception.getMessage(),
                request.getDescription(false)
        );

        return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR)
                .body(message);
    }
}

5. 표준 오류 응답 생성

오류 메시지를 구조화하기 위한 표준 오류 응답 클래스를 정의합니다.

package com.example.SpringBootRefresher.entity;

public class ErrorMessage {
    private int statusCode;
    private String message;
    private String description;

    public ErrorMessage(int statusCode, String message, String description) {
        this.statusCode = statusCode;
        this.message = message;
        this.description = description;
    }

    // Getters and setters

    public int getStatusCode() {
        return statusCode;
    }

    public void setStatusCode(int statusCode) {
        this.statusCode = statusCode;
    }

    public String getMessage() {
        return message;
    }

    public void setMessage(String message) {
        this.message = message;
    }

    public String getDescription() {
        return description;
    }

    public void setDescription(String description) {
        this.description = description;
    }
}

6. 유효성 검사 오류 처리

Spring Boot는 Bean 검증(JSR-380)과 잘 통합됩니다. 유효성 검사 오류를 전역적으로 처리하려면 @ControllerAdvice.
를 사용하세요.

package com.example.SpringBootRefresher.error;

import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.validation.FieldError;
import org.springframework.web.bind.MethodArgumentNotValidException;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseStatus;
import org.springframework.web.context.request.WebRequest;
import java.util.HashMap;
import java.util.Map;

@ControllerAdvice
@ResponseStatus
public class ValidationExceptionHandler extends ResponseEntityExceptionHandler {

    @ExceptionHandler(MethodArgumentNotValidException.class)
    public ResponseEntity> handleValidationExceptions(MethodArgumentNotValidException ex) {
        Map errors = new HashMap();
        ex.getBindingResult().getAllErrors().forEach((error) -> {
            String fieldName = ((FieldError) error).getField();
            String errorMessage = error.getDefaultMessage();
            errors.put(fieldName, errorMessage);
        });
        return new ResponseEntity(errors, HttpStatus.BAD_REQUEST);
    }
}

7. 간단한 예외에 @ResponseStatus 사용하기

간단한 경우 @ResponseStatus로 예외 클래스에 주석을 달아 HTTP 상태 코드를 지정할 수 있습니다.

package com.example.SpringBootRefresher.exception;

import org.springframework.http.HttpStatus;
import org.springframework.web.bind.annotation.ResponseStatus;

@ResponseStatus(HttpStatus.NOT_FOUND)
public class DepartmentNotFoundException extends RuntimeException {
    public DepartmentNotFoundException(String message) {
        super(message);
    }
}

8. 생산 모범 사례

  1. 일관된 오류 응답: 애플리케이션이 일관되고 구조화된 오류 응답을 반환하는지 확인하세요. 표준 오류 응답 클래스를 사용하세요.
  2. 로깅: 디버깅 및 모니터링 목적으로 예외를 기록합니다. 민감한 정보가 로그에 노출되지 않도록 하세요.
  3. 사용자 친화적인 메시지: 사용자에게 친숙한 오류 메시지를 제공합니다. 내부 세부 정보나 스택 추적을 사용자에게 노출하지 마세요.
  4. 보안: 민감한 데이터가 노출되지 않도록 오류 응답에 포함된 정보에 주의하세요.
  5. 문서화: 팀과 향후 유지관리자를 위해 예외 처리 전략을 문서화합니다.

요약

Spring Boot의 예외 처리에는 오류를 효과적으로 관리하기 위해 @ExceptionHandler, @ControllerAdvice 및 @ResponseStatus와 같은 주석을 사용하는 작업이 포함됩니다. 사용자 지정 예외를 만들고, 유효성 검사 오류를 처리하고, 모범 사례를 따르면 오류를 적절하게 처리하고 사용자에게 의미 있는 피드백을 제공하는 강력한 애플리케이션을 구축할 수 있습니다. Java 17 기능을 사용하면 애플리케이션이 Java 생태계의 최신 개선 사항을 활용할 수 있습니다.

릴리스 선언문 이 글은 https://dev.to/isaactony/Exception-handling-in-spring-boot-2lgd?1에서 복제됩니다.1 침해 내용이 있는 경우, [email protected]으로 연락하여 삭제하시기 바랍니다.
최신 튜토리얼 더>

부인 성명: 제공된 모든 리소스는 부분적으로 인터넷에서 가져온 것입니다. 귀하의 저작권이나 기타 권리 및 이익이 침해된 경우 자세한 이유를 설명하고 저작권 또는 권리 및 이익에 대한 증거를 제공한 후 이메일([email protected])로 보내주십시오. 최대한 빨리 처리해 드리겠습니다.

Copyright© 2022 湘ICP备2022001581号-3