diff --git a/src/main/java/com/example/UMC/domain/test/controller/TestController.java b/src/main/java/com/example/UMC/domain/test/controller/TestController.java new file mode 100644 index 0000000..7532470 --- /dev/null +++ b/src/main/java/com/example/UMC/domain/test/controller/TestController.java @@ -0,0 +1,25 @@ +package com.example.UMC.domain.test.controller; + +import com.example.UMC.domain.user.exception.code.UserErrorCode; +import com.example.UMC.global.apiPayload.ApiResponse; +import com.example.UMC.global.apiPayload.code.GeneralSucessCode; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +@RestController +@RequestMapping("/test") +public class TestController { + + //성공 + @GetMapping("sucess") + public ApiResponse sucessTest() { + return ApiResponse.onSucess(GeneralSucessCode.OK, "요청 정상 처리"); + } + + //실패 + @GetMapping("fail") + public ApiResponse failTest() { + return ApiResponse.onFailure(UserErrorCode.USER_NOT_FOUND, null); + } +} diff --git a/src/main/java/com/example/UMC/domain/user/exception/UserException.java b/src/main/java/com/example/UMC/domain/user/exception/UserException.java new file mode 100644 index 0000000..ab2bb87 --- /dev/null +++ b/src/main/java/com/example/UMC/domain/user/exception/UserException.java @@ -0,0 +1,10 @@ +package com.example.UMC.domain.user.exception; + +import com.example.UMC.global.apiPayload.code.BaseErrorCode; +import com.example.UMC.global.apiPayload.exception.GeneralException; + +public class UserException extends GeneralException { + public UserException(BaseErrorCode code) { + super(code); + } +} diff --git a/src/main/java/com/example/UMC/domain/user/exception/code/UserErrorCode.java b/src/main/java/com/example/UMC/domain/user/exception/code/UserErrorCode.java new file mode 100644 index 0000000..6cafc29 --- /dev/null +++ b/src/main/java/com/example/UMC/domain/user/exception/code/UserErrorCode.java @@ -0,0 +1,17 @@ +package com.example.UMC.domain.user.exception.code; + +import com.example.UMC.global.apiPayload.code.BaseErrorCode; +import lombok.AllArgsConstructor; +import lombok.Getter; +import org.springframework.http.HttpStatus; + +@Getter +@AllArgsConstructor +public enum UserErrorCode implements BaseErrorCode { + USER_NOT_FOUND(HttpStatus.NOT_FOUND, "USER4001", "해당 사용자를 찾을 수 없습니다."), + DUPLICATE_EMAIL(HttpStatus.BAD_REQUEST, "USER4002","이미 존재하는 이메일입니다."); + + private final HttpStatus status; + private final String code; + private final String message; +} diff --git a/src/main/java/com/example/UMC/global/apiPayload/ApiResponse.java b/src/main/java/com/example/UMC/global/apiPayload/ApiResponse.java new file mode 100644 index 0000000..c483d49 --- /dev/null +++ b/src/main/java/com/example/UMC/global/apiPayload/ApiResponse.java @@ -0,0 +1,25 @@ +package com.example.UMC.global.apiPayload; + +import com.example.UMC.global.apiPayload.code.BaseErrorCode; +import com.example.UMC.global.apiPayload.code.BaseSucessCode; +import lombok.AllArgsConstructor; +import lombok.Getter; + +@Getter +@AllArgsConstructor +public class ApiResponse { + private final Boolean isSucess; + private final String code; + private final String message; + private final T result; + + // 성공 응답 + public static ApiResponse onSucess(BaseSucessCode code, T result){ + return new ApiResponse<>(true, code.getCode(), code.getMessage(), result); + } + + //실패 응답 + public static ApiResponse onFailure(BaseErrorCode code, T result) { + return new ApiResponse<>(false, code.getCode(), code.getMessage(), result); + } +} diff --git a/src/main/java/com/example/UMC/global/apiPayload/code/BaseErrorCode.java b/src/main/java/com/example/UMC/global/apiPayload/code/BaseErrorCode.java new file mode 100644 index 0000000..032d787 --- /dev/null +++ b/src/main/java/com/example/UMC/global/apiPayload/code/BaseErrorCode.java @@ -0,0 +1,9 @@ +package com.example.UMC.global.apiPayload.code; + +import org.springframework.http.HttpStatus; + +public interface BaseErrorCode { + HttpStatus getStatus(); + String getCode(); + String getMessage(); +} diff --git a/src/main/java/com/example/UMC/global/apiPayload/code/BaseSucessCode.java b/src/main/java/com/example/UMC/global/apiPayload/code/BaseSucessCode.java new file mode 100644 index 0000000..5c17812 --- /dev/null +++ b/src/main/java/com/example/UMC/global/apiPayload/code/BaseSucessCode.java @@ -0,0 +1,6 @@ +package com.example.UMC.global.apiPayload.code; + +public interface BaseSucessCode { + String getCode(); + String getMessage(); +} diff --git a/src/main/java/com/example/UMC/global/apiPayload/code/GeneralErrorCode.java b/src/main/java/com/example/UMC/global/apiPayload/code/GeneralErrorCode.java new file mode 100644 index 0000000..ac4b1ce --- /dev/null +++ b/src/main/java/com/example/UMC/global/apiPayload/code/GeneralErrorCode.java @@ -0,0 +1,18 @@ +package com.example.UMC.global.apiPayload.code; + +import lombok.AllArgsConstructor; +import lombok.Getter; +import org.springframework.http.HttpStatus; + +@Getter +@AllArgsConstructor +public enum GeneralErrorCode implements BaseErrorCode { + BAD_REQUEST(HttpStatus.BAD_REQUEST, "COMMON400", "잘못된 요청입니다."), + UNAUTHORIZED(HttpStatus.UNAUTHORIZED, "COMMON401", "인증이 필요합니다."), + FORBIDDEN(HttpStatus.FORBIDDEN, "COMMON403", "접근이 거부되었습니다."), + INTERNAL_SERVER_ERROR(HttpStatus.INTERNAL_SERVER_ERROR, "COMMON500", "서버 오류가 발생했습니다."); + + private final HttpStatus status; + private final String code; + private final String message; +} diff --git a/src/main/java/com/example/UMC/global/apiPayload/code/GeneralSucessCode.java b/src/main/java/com/example/UMC/global/apiPayload/code/GeneralSucessCode.java new file mode 100644 index 0000000..f6a8124 --- /dev/null +++ b/src/main/java/com/example/UMC/global/apiPayload/code/GeneralSucessCode.java @@ -0,0 +1,14 @@ +package com.example.UMC.global.apiPayload.code; + +import lombok.AllArgsConstructor; +import lombok.Getter; + +@Getter +@AllArgsConstructor +public enum GeneralSucessCode implements BaseSucessCode{ + OK("COMMON200", "요청이 성공적으로 처리되었습니다."), + CREATED("COMMON201", "리소스가 성공적으로 생성되었습니다."); + + private final String code; + private final String message; +} diff --git a/src/main/java/com/example/UMC/global/apiPayload/exception/GeneralException.java b/src/main/java/com/example/UMC/global/apiPayload/exception/GeneralException.java new file mode 100644 index 0000000..64efcab --- /dev/null +++ b/src/main/java/com/example/UMC/global/apiPayload/exception/GeneralException.java @@ -0,0 +1,12 @@ +package com.example.UMC.global.apiPayload.exception; + +import com.example.UMC.global.apiPayload.code.BaseErrorCode; +import lombok.AllArgsConstructor; +import lombok.Getter; + +@Getter +@AllArgsConstructor +public class GeneralException extends RuntimeException{ + + private final BaseErrorCode code; +} diff --git a/src/main/java/com/example/UMC/global/apiPayload/handler/GeneralExceptionAdvice.java b/src/main/java/com/example/UMC/global/apiPayload/handler/GeneralExceptionAdvice.java new file mode 100644 index 0000000..67fc30f --- /dev/null +++ b/src/main/java/com/example/UMC/global/apiPayload/handler/GeneralExceptionAdvice.java @@ -0,0 +1,27 @@ +package com.example.UMC.global.apiPayload.handler; + +import com.example.UMC.global.apiPayload.ApiResponse; +import com.example.UMC.global.apiPayload.code.BaseErrorCode; +import com.example.UMC.global.apiPayload.code.GeneralErrorCode; +import com.example.UMC.global.apiPayload.exception.GeneralException; +import org.springframework.http.ResponseEntity; +import org.springframework.web.bind.annotation.ExceptionHandler; +import org.springframework.web.bind.annotation.RestControllerAdvice; + +@RestControllerAdvice +public class GeneralExceptionAdvice { + + // 애플리케이션에서 발생하는 커스텀 예외를 처리(내가 만든 예외) + @ExceptionHandler(GeneralException.class) + public ResponseEntity> handleException(GeneralException ex) { + return ResponseEntity.status(ex.getCode().getStatus()) + .body(ApiResponse.onFailure(ex.getCode(), null)); + } + // 그 외의 정의되지 않은 모든 예외 처리(스프링 내부에서 처리) + @ExceptionHandler(Exception.class) + public ResponseEntity> handleException(Exception ex) { + BaseErrorCode code = GeneralErrorCode.INTERNAL_SERVER_ERROR; + return ResponseEntity.status(code.getStatus()) + .body(ApiResponse.onFailure(code, ex.getMessage())); + } +}