Week9

아야하면우유·2025년 7월 1일

HSL

목록 보기
5/6

Global 패키지와 예외처리


Exception 처리

  • 예외가 발생할 수 있는 계층 
    - 모든 컨트롤러, 모든 도메인 등...
    Global package에서 제어
     
  • In Business logic
    → 해당 도메인 내에서 예외처리 반환

const/StaticValue


Http Status 관련해서 정적, 불변으로 관리하기 위한 클래스.

public class StaticValue {

    // Success Code
    public static final int OK = 200;
    public static final int CREATED = 201;
    public static final int NO_CONTENT = 204;

    // Error Code
    public static final int BAD_REQUEST = 400;
    public static final int UNAUTHORIZED = 401;
    public static final int FORBIDDEN = 403;
    public static final int NOT_FOUND = 404;
    public static final int METHOD_NOT_ALLOWED = 405;
    public static final int CONFLICT = 409;
    public static final int INTERNAL_SERVER_ERROR = 500;

}

  


Response - ResponseCode


Front-end 와 통신하기 위하여, 만드는 Json 형태의 클래스

  • BaseResponse

@Getter
@ToString
@RequiredArgsConstructor
public class BaseResponse {
    private final Boolean isSuccess;
    private final String code;
    private final String message;

    private final String timeStamp = LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"));

	// 성공 여부와 BaseResponseCode
    public static BaseResponse of(Boolean isSuccess, BaseResponseCode baseResponseCode) {
        return new BaseResponse(isSuccess, baseResponseCode.getCode(), baseResponseCode.getMessage());
    }
    // 성공 여부와 BaseResponse, 메세지
    public static BaseResponse of(Boolean isSuccess, BaseResponseCode baseResponseCode, String message) {
        return new BaseResponse(isSuccess, baseResponseCode.getCode(), message);
    }
    // custom - 성공여부, 코드, 메세지 전부
    public static BaseResponse of(Boolean isSuccess, String code, String message) {
        return new BaseResponse(isSuccess, code, message);
    }
  • isSuccess : 통신 성공 여부
  • code : Http Status 중, 어떤 상태인지 (200 OK, 403 Forbidden ...)
  • message : 실패한 이유

  • Success & ErrorResponse

// Success Case
// 200 OK 응답
    public static <T> SuccessResponse<T> from(T data) {
        return new SuccessResponse<>(data, SuccessResponseCode.SUCCESS_OK);
    }
    
// Error Case
// No Data
	public static ErrorResponse<?> from(BaseResponseCode baseResponseCode) {
        return new ErrorResponse<>(null, baseResponseCode);
    }

 


Exception


RunTime 중에서, 터지는 예외에 대해 알맞게 분기하여 예외를 던짐.

  • Global

    BaseResponseCode를 상속받아서, isSuccess, code, message를 알맞게 입력해줌
    @RestControllerAdvice 를 통해서, 예외 발생 시, 자동으로 해당 예외를 던짐
	// @RequesBody - Valid(Validated)
    // like NotNull, NotBlank ...
    @ExceptionHandler(MethodArgumentNotValidException.class)
    public ResponseEntity<ErrorResponse<?>> handleMethodArgumentNotValidException(MethodArgumentNotValidException e) {
        log.error("MethodArgumentNotValidException : {}", e.getMessage(), e);
        ErrorResponse<?> errorResponse = ErrorResponse.of(
                ErrorResponseCode.INVALID_HTTP_MESSAGE_BODY,
                e.getFieldError().getDefaultMessage());
        return ResponseEntity.status(errorResponse.getHttpStatus()).body(errorResponse);
    }
  • Domain

    해당 Entity 내에서,
    enum - BaseResponseCode 상속,
    exception - BaseException 상속
    클래스 두 개를 정의하고, 던질 예외에 맞는 Http Status를 오버라이딩한다.
// UserErrorCode
@Getter
@AllArgsConstructor
public enum UserErrorCode implements BaseResponseCode {
    USER_ALREADY_EXIST_409("USER_409", CONFLICT, "이미 존재하는 사용자입니다.");

    private final String code;
    private final int httpStatus;
    private final String message;

}

// UserAlreadyExsistException
public class UserAlreadyExistException extends BaseException {
    public UserAlreadyExistException() { super(UserErrorCode.USER_ALREADY_EXIST_409); }
}

 


CORS 에러와 WebConfig


Cross-Origin-Resource-Shared : 서로 출처가 다른 자원 요구 중
이라는 뜻이다. 원래 브라우저는 같은 출처에서의 자원끼리만 공유되게끔 설정해두어서,

http://localhost:8080 <-> http://ANOTHER_URL

위와 같은 방식으로 자원을 공유하려고 시도할 시, CORS 에러가 발생한다.

이를 설정으로 허용해줄 수 있는데, 그 방법은 다음과 같다.

@Configuration
public class WebConfig implements WebMvcConfigurer {
    @Override
    public void addCorsMappings(CorsRegistry registry) {
        registry.addMapping("/**")
                .allowedOriginPatterns("*")
				/* 위의 경우, 여러 URL의 CORS를 허용하고 싶을 때
                 * 현재방식의 경우, WildCard 문자인 '*'로 모든 URL 허용중이다.
				 * allowedOrigins() < 임의의 1개 도메인 허용
                 */
                .allowCredentials(true);
    }
}

추가적으로...


Spring의 MVC 패턴(Dispatcher Servlet 등)이라던가,
예외를 던졌을 때 어떻게 잡아지는지,
Front-End와 통신할 때 발생할 수 있는 여러가지 예외,
그리고 비즈니스 로직 간 예외가 발생했을 때 어떻게 대처해야 하는지?

이런 것들을 공부해서, 예외 케이스를 마음껏 설정해두고 싶다.

profile
우유가 넘어지면 아야

0개의 댓글