Swagger 최신 버전과 RestControllerAdvice 어노테이션을 함께 사용했을 때 - lets-go-trip/treaXure-backend GitHub Wiki

Swagger 최신 버전과 RestControllerAdvice 어노테이션을 함께 사용했을 때

1. 오류 현상


: 모든 API 호출에서 500 Internal Server Error 발생, 응답 바디 { "code": "SE", "message": "Server error." }

  • 동일 코드가 Postman·curl 로도 재현 → 서버 내부 예외 확정
  • IDE 콘솔 로그: java.lang.NoSuchMethodError / Could not resolve method parameter 등 Springdoc 리플렉션 오류

2. 원인 분석


: springdoc-openapi 최신 버전 + 커스텀 @RestControllerAdvice 조합에서 핸들러 메서드 시그니처 파싱 실패

  • OpenAPI 2.5.x 부터 ProblemDetail 파라미터가 추가되며 리플렉션 경로 변경
  • 우리 프로젝트 GlobalExceptionHandlerResponseEntity<ErrorResponse> 를 반환 → Springdoc 가파르게 스캔하다 예외

3. 해결 과정


  • Step 1 버전 다운그레이드
    • Gradle plugins:
      • org.springframework.boot 3.4.5 → 3.4.0
      • io.spring.dependency-management 1.1.7 → 1.1.5
    • 버전을 낮추면 500 오류는 즉시 사라지지만, 스키마 경고는 여전히 존재
  • Step 2 @Hidden 어노테이션 적용
    • @RestControllerAdvice 클래스에 @Hidden 추가하여 Swagger 스캔 제외
    • springdoc 버전을 다시 2.5.0 으로 복원해도 오류 재발하지 않음
  • Step 3 재검증
    • DevTools 200 OK·OPTIONS 204 확인

@Hidden 어노테이션 적용

  • @RestControllerAdvice 클래스에 @Hidden 추가하여 Swagger 스캔 제외
  • 버전을 2.5.0 으로 복원해도 500 오류 재발하지 않음

4. 적용 코드


@Hidden              // springdoc-openapi 스캔 제외
@RestControllerAdvice
public class GlobalExceptionHandler {

    @ExceptionHandler(CustomException.class)
    public ResponseEntity<ErrorResponse> handleCustom(CustomException ex) {
        ErrorResponse body = ErrorResponse.of(ex.getCode(), ex.getMessage());
        return ResponseEntity.status(ex.getStatus()).body(body);
    }
}

// build.gradle
implementation "org.springdoc:springdoc-openapi-starter-webmvc-ui:2.5.0"

5. 검증 결과


: 버전 복원 + @Hidden 이후 Swagger UI 및 실제 클라이언트 모두 200/4xx 정상 동작, 콘솔 예외 로그 제거 확인

  • ./gradlew clean build && ./gradlew bootRun 후 전체 통합 테스트 통과

6. 교훈


: Swagger(OpenAPI) 스캔 대상이 아닌 Advice·Filter 는 @Hidden 으로 명시 제외하자

  • 라이브러리 버전 다운은 임시 조치, 루트 원인은 리플렉션 대상 과다
  • 새 버전 도입 시 전체 통합 테스트 & Swagger UI 호출으로 조기 검증 필요