Curl Up Black Cat


😎 μ„œλ‘ 

μ•ˆλ…•ν•˜μ„Έμš”! μ˜€λŠ˜μ€ Spring Boot μ—μ„œ API 응닡과 μ˜ˆμ™Έ 처리 λͺ¨λΈμ„ κ΅¬μΆ•ν•΄λ΄€λ˜ λ‚΄μš©μ„ κ³΅μœ ν•΄ 보렀고 ν•©λ‹ˆλ‹€. μ½”λ“œλ“€λ„ ν•˜λ‚˜ν•˜λ‚˜ 뢄석해 λ³Όκ»˜μš”. μŠ€νƒ€νŠΈ~!

 


1. ResponseModel - 응닡 λͺ¨λΈ

λ¨Όμ €, λͺ¨λ“  API 응닡에 κ³΅ν†΅μ μœΌλ‘œ μ‚¬μš©λ  ResponseModel 을 μ‚΄νŽ΄λ΄…λ‹ˆλ‹€.

@Getter
@Setter
@ToString
@AllArgsConstructor(staticName = "of")
public class ResponseModel<T> {
    private boolean success;
    private T data;
    private ErrorModel error;

    public static <T> ResponseModel<T> of(boolean success, T data) {
        return ResponseModel.of(success, data, null);
    }

    public static ResponseModel of(boolean success, ErrorCode code) {
        return ResponseModel.of(success, null, ErrorModel.of(code.name(), code.getMessage(), null));
    }

    public static ResponseModel of(boolean success, ErrorCode code, Exception ex) {
        return ResponseModel.of(success, null, code, ex);
    }

    public static <T> ResponseModel<T> of(boolean success, T data, ErrorCode code, Exception ex) {
        final ErrorModel error = (code != null) ? ErrorModel.of(code, ex) : null;
        return ResponseModel.of(success, data, error);
    }
}

μ£Όμš” ꡬ성 μš”μ†Œ:

1. success: μš”μ²­ 처리의 성곡 μ—¬λΆ€λ₯Ό λ‚˜νƒ€λƒ…λ‹ˆλ‹€.

2. data: μš”μ²­μ— λŒ€ν•œ κ²°κ³Ό 데이터λ₯Ό ν¬ν•¨ν•©λ‹ˆλ‹€.

3. error: λ°œμƒν•œ 였λ₯˜μ— λŒ€ν•œ 정보λ₯Ό ν¬ν•¨ν•˜λŠ” ErrorModel 객체 μž…λ‹ˆλ‹€.

 

ResponseModel μ—λŠ” μ—¬λŸ¬ static 생성 λ©”μ„œλ“œκ°€ ν¬ν•¨λ˜μ–΄ μžˆμŠ΅λ‹ˆλ‹€. 이 λ©”μ„œλ“œλ“€μ„ 톡해 성곡 λ˜λŠ” 였λ₯˜ 상황에 따라 μ‰½κ²Œ 응닡 객체λ₯Ό ꡬ성할 수 μžˆμŠ΅λ‹ˆλ‹€.

 

2. ErrorModel - μ—λŸ¬ λͺ¨λΈ

ErrorModel 은 였λ₯˜μ— λŒ€ν•œ 정보λ₯Ό ν‘œμ€€ν™”ν•˜μ—¬ μ „λ‹¬ν•˜κΈ° μœ„ν•œ λͺ¨λΈμž…λ‹ˆλ‹€.

 

package com.board.backend.model;

import com.board.backend.common.ErrorCode;
import com.board.backend.common.utils.ObjectUtil;
import com.board.backend.common.utils.StringUtil;
import lombok.AllArgsConstructor;
import lombok.Getter;
import lombok.Setter;
import lombok.ToString;

@Getter
@Setter
@ToString
@AllArgsConstructor(staticName = "of")
public class ErrorModel {
    private String code;
    private String message;
    private ErrorData data;

    @Getter
    @Setter
    @ToString
    @AllArgsConstructor(staticName = "of")
    public static class ErrorData {
        private String exceptionMessage;
        private String stackTrace;
    }

    public static ErrorModel of(ErrorCode code, Exception ex) {
        final String exceptionMessage = ObjectUtil.nonEmpty(ex) ? ex.getMessage() : null;
        final String stackTrace = ObjectUtil.nonEmpty(ex) ? getStackTraceAsString(ex) : null;
        final ErrorData data = (StringUtil.nonEmpty(exceptionMessage) || StringUtil.nonEmpty(stackTrace)) ? ErrorData.of(exceptionMessage, stackTrace) : null;
        return ErrorModel.of(code.name(), code.getMessage(), data);
    }

    private static String getStackTraceAsString(Exception ex) {
        final StringBuilder sb = new StringBuilder();
        for (StackTraceElement element : ex.getStackTrace()) {
            sb.append(element.toString());
            sb.append("\n");
        }
        return sb.toString();
    }
}

μ£Όμš” ꡬ성 μš”μ†Œ:

1. code: 였λ₯˜ μ½”λ“œλ₯Ό λ‚˜νƒ€λƒ…λ‹ˆλ‹€.

2. message: 였λ₯˜ λ©”μ‹œμ§€λ₯Ό λ‚˜νƒ€λƒ…λ‹ˆλ‹€.

3. data: 였λ₯˜ λ°œμƒ μ‹œμ˜ μΆ”κ°€ 정보λ₯Ό λ‚˜νƒ€λ‚΄λŠ” ErrorData κ°μ²΄μž…λ‹ˆλ‹€.

 

ErrorData ν΄λž˜μŠ€λŠ” λ°œμƒν•œ μ˜ˆμ™Έμ˜ λ©”μ‹œμ§€μ™€ μŠ€νƒ 트레이슀 정보λ₯Ό ν¬ν•¨ν•©λ‹ˆλ‹€. 이λ₯Ό 톡해 였λ₯˜μ˜ 원인을 λ”μš± μžμ„Ένžˆ νŒŒμ•…ν•  수 μžˆμŠ΅λ‹ˆλ‹€.(μŠ€νƒ νŠΈλ ˆμ΄μŠ€λž€? ν”„λ‘œκ·Έλž¨μ—μ„œ μ˜ˆμ™Έκ°€ λ°œμƒν–ˆμ„ λ•Œ ν•΄λ‹Ή μ˜ˆμ™Έμ˜ λ°œμƒ 경둜λ₯Ό μΆ”μ ν•˜λŠ” μ •λ³΄μž…λ‹ˆλ‹€. μ΄λŠ” λ©”μ„œλ“œ 호좜 μˆœμ„œμ™€ 라인 번호λ₯Ό ν¬ν•¨ν•˜μ—¬ 였λ₯˜κ°€ λ°œμƒν•œ μœ„μΉ˜μ™€ κ·Έ 원인을 확인할 수 있게 λ„μ™€μ€λ‹ˆλ‹€.)

 

3. ErrorCode - μ—λŸ¬ μ½”λ“œ

@Getter
@AllArgsConstructor
public enum ErrorCode {
    SERVER_ERROR("μ„œλ²„ μ—λŸ¬"),
    ARGUMENT_TYPE_MISMATCH("잘λͺ»λœ νŒŒλΌλ―Έν„°νƒ€μž…μ΄ μ „λ‹¬λ˜μ—ˆμŠ΅λ‹ˆλ‹€."),
    BOARD_NOT_FOUND("글이 μ‘΄μž¬ν•˜μ§€ μ•ŠμŠ΅λ‹ˆλ‹€");
    ...
    private String message;
}

각 였λ₯˜ μœ ν˜•μ— λŒ€ν•œ λ©”μ‹œμ§€λ₯Ό ν•¨κ»˜ μ œκ³΅ν•˜μ—¬ μ‚¬μš©μžμ—κ²Œ 의미 μžˆλŠ” 였λ₯˜ λ©”μ‹œμ§€λ₯Ό 전달 ν•©λ‹ˆλ‹€. enum νƒ€μž…μœΌλ‘œ μ½”λ“œμ™€ λ©”μ‹œμ§€λ₯Ό ν•¨κ»˜ κ΄€λ¦¬ν•˜μ˜€μŠ΅λ‹ˆλ‹€.

 

4. ExceptionAdvice - μ „μ—­ μ˜ˆμ™Έ 처리기

Spring Boot μ—μ„œ μ˜ˆμ™Έ 처리의 μ€‘μš”μ„±μ„ κ°•μ‘°ν•˜λ©°, 이λ₯Ό μœ„ν•΄ @ControllerAdvice 와 @ExceptionHandler λ₯Ό 톡해 효과적인 μ „μ—­ μ˜ˆμ™Έ 처리 방식을 μ œκ³΅ν•©λ‹ˆλ‹€.

@ControllerAdvice
public class ExceptionAdvice {
    @ExceptionHandler(value = {Exception.class})
    public ResponseEntity handleException(Exception ex, WebRequest request) {
        final ResponseModel responseModel = ResponseModel.of(false, ErrorCode.SERVER_ERROR, ex);
        return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body(responseModel);
    }

    @ExceptionHandler(value = {MethodArgumentTypeMismatchException.class})
    public ResponseEntity handleTypeException(Exception ex) {
        final ResponseModel<Object> responseModel = ResponseModel.of(false, ErrorCode.ARGUMENT_TYPE_MISMATCH,  ex);
        return ResponseEntity.status(HttpStatus.BAD_REQUEST).body(responseModel);
    }
    ...
}

 

1) @ControllerAdvice 의 μ—­ν• 

@ControllerAdvice λŠ” Spring μ—μ„œ λͺ¨λ“  μ»¨νŠΈλ‘€λŸ¬μ—μ„œ λ°œμƒν•  수 μžˆλŠ” μ˜ˆμ™Έλ“€μ„ ν•œκ³³μ—μ„œ κ΄€λ¦¬ν•˜κ³  μ²˜λ¦¬ν•˜κΈ° μœ„ν•΄ λ„μž…λœ μ–΄λ…Έν…Œμ΄μ…˜μž…λ‹ˆλ‹€. 이λ₯Ό 톡해 μ½”λ“œμ˜ 쀑볡을 쀄이고, μΌκ΄€λœ μ˜ˆμ™Έ 처리 λ‘œμ§μ„ ꡬ성할 수 λ„μ™€μ€λ‹ˆλ‹€. 

 

2) @ExceptionHandler 

@ExceptionHandler λŠ” νŠΉμ • μ˜ˆμ™Έλ₯Ό μ²˜λ¦¬ν•  λ©”μ„œλ“œλ₯Ό μ§€μ •ν•˜κΈ° μœ„ν•œ Spring MVC 의 μ–΄λ…Έν…Œμ΄μ…˜μž…λ‹ˆλ‹€. κ·Έ μžμ²΄λ‘œλ„ μœ μš©ν•˜μ§€λ§Œ, @ControllerAdvice와 κ²°ν•©ν•˜μ—¬ μ‚¬μš©ν•  경우, μ• ν”Œλ¦¬μΌ€μ΄μ…˜ μ „μ²΄μ˜ μ˜ˆμ™Έλ₯Ό μ€‘μ•™μ—μ„œ 효율적으둜 관리할 수 있게 λ©λ‹ˆλ‹€.

 

μ˜ˆμ‹œ:

// 단일 지정
@ExceptionHandler({CustomException.class})

// 닀쀑 지정
@ExceptionHandler({CustomException1.class, CustomException2.class, CustomException3.class})

μ΄λ ‡κ²Œ μ„€μ •ν•˜λ©΄, μœ„μ—μ„œ μ§€μ •λœ μ˜ˆμ™Έλ“€μ΄ λ°œμƒν–ˆμ„ λ•Œ λ™μΌν•œ λ°©μ‹μœΌλ‘œ μ²˜λ¦¬λ©λ‹ˆλ‹€.

 

3) ν™•μž₯μ„±

@ControllerAdvice 의 μž₯점쀑 ν•˜λ‚˜λŠ” κ·Έ ν™•μž₯μ„±μž…λ‹ˆλ‹€. μƒˆλ‘œμš΄ μ˜ˆμ™Έλ₯Ό μΆ”κ°€ν•˜κ±°λ‚˜ μ˜ˆμ™Έ 처리 방식을 μˆ˜μ •ν•΄μ•Ό ν•  λ•Œ, @ExceptionHandler λ₯Ό μ μ ˆν•œ λ©”μ„œλ“œμ— μΆ”κ°€ν•˜κ±°λ‚˜ μˆ˜μ •ν•¨μœΌλ‘œμ¨ μ€‘μ•™μ—μ„œ μ˜ˆμ™Έ 처리 λ‘œμ§μ„ μ‰½κ²Œ κ΄€λ¦¬ν•˜κ³  ν™•μž₯ν•  수 μžˆμŠ΅λ‹ˆλ‹€.


🀠 결둠

Spring Boot ν™˜κ²½μ—μ„œ λ‚˜λ¦„λŒ€λ‘œ μƒκ°ν•΄μ„œ κ΅¬ν˜„ν–ˆλ˜ 응닡과 μ˜ˆμ™Έ 처리 방법에 λŒ€ν•΄ μ•Œμ•„λ³΄μ•˜μŠ΅λ‹ˆλ‹€. μΌκ΄€λœ 응닡과 μ •ν™•ν•œ μ˜ˆμ™Έ μ²˜λ¦¬λŠ” API의 신뒰성을 λ†’μ΄λŠ” 핡심 μš”μ†Œλ‘œ, 이λ₯Ό 톡해 μ‚¬μš©μžμ™€μ˜ μ‹ λ’° 관계λ₯Ό κ΅¬μΆ•ν•˜κ³ , κ°œλ°œνŒ€ κ°„μ˜ ν˜‘μ—… νš¨μœ¨μ„ 높일 수 μžˆμŠ΅λ‹ˆλ‹€. πŸ™‚

+ Recent posts