π μλ‘
μλ νμΈμ! μ€λμ 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μ μ λ’°μ±μ λμ΄λ ν΅μ¬ μμλ‘, μ΄λ₯Ό ν΅ν΄ μ¬μ©μμμ μ λ’° κ΄κ³λ₯Ό ꡬμΆνκ³ , κ°λ°ν κ°μ νμ ν¨μ¨μ λμΌ μ μμ΅λλ€. π
'π» νλ‘κ·Έλλ° > π Spring' μΉ΄ν κ³ λ¦¬μ λ€λ₯Έ κΈ
Springμμ μλͺ»λ λ©μμ§ μμ² νΈλ€λ§νκΈ° (0) | 2023.08.19 |
---|---|
μ€νλ§ λΆνΈ JSON μλ΅ Null κ° μλ μ κ±° (0) | 2023.08.14 |
MyBatis XML Mapper μμ Java λ΄λΆ ν΄λμ€ μ°Έμ‘°νκΈ° (0) | 2023.08.13 |