Spring MVC에서 컨트롤러에 쿼리 파라미터를 받기 위해 @RequestParam을 사용할 때
어떤 상황에서는 명백히 올바른 파라미터를 전달했음에도 서버가 400 Bad Request를 응답하는 경우가 있다.
최근 내가 겪었던 상황이 그랬다. 단순히 @RequestParam Integer data 하나 받는 API였고 Postman으로 ?data=10이라는 정수 파라미터를 넣었는데도 400 오류가 발생했다.
파라미터 누락이나 형식 오류라고 생각했는데 로그를 보니 java.lang.IllegalArgumentException이 발생하고 있었고
stack trace에서 핵심 메시지를 보니 이렇게 쓰여있었다.
Name for argument of type [java.lang.Integer] not specified, and parameter name information not available via reflection. Ensure that the compiler uses the '-parameters' flag.”
이 에러 메시지가 말하는 바가 뭔가 찾아보니 @RequestParam을 사용할 때 우리는 흔히 @RequestParam Integer data 이런 식으로 쓰는데 자바 컴파일러는 기본적으로 메서드의 파라미터 이름을 .class 파일에 포함시키지 않는 다는 거였다.
즉 우리가 코드에 data라고 적어도 컴파일된 결과물엔 그 이름이 존재하지 않는다.
Spring은 파라미터 이름을 리플렉션을 통해 알아내야 하는데 이름이 아예 없으니 내부적으로 이게 무슨 파라미터인지 모르겠다고 판단해 바인딩을 실패시키고 400 오류를 발생시키는 것이다.
해결하는 방법은 꽤 간단한데 @RequestParam("data")처럼 파라미터 이름을 명시해주는 것이다.
이렇게 하면 Spring은 이름을 추론할 필요가 없으므로 리플렉션이나 컴파일러 설정에 영향을 받지 않고 올바른 응답을 준다.
두 번째 방법은 Java 컴파일러에게 메서드 파라미터 이름을 .class에 포함시켜달라고 지시하는 것이다.
build.gradle 파일에 options.compilerArgs += "-parameters"를 넣어주면 된다. 이 설정이 적용되면 @RequestParam에 이름을 명시하지 않아도 내부적으로 Spring이 data라는 이름을 인식할 수 있게 된다.
비슷한 문제가 @PathVariable에서도 발생할 수 있다. @PathVariable 역시 경로 변수의 이름을 추론하는 구조인데 파라미터 이름 정보가 없으면 어떤 경로 변수에 바인딩 해야할지를 몰라서 에러를 던지게 된다.
따라서 @PathVariable도 가능한 한 "id"와 같이 이름을 명시하거나 컴파일러 설정을 해주는 것이 좋다.
@ModelAttribute나 @RequestBody는 다소 다르다. 이 둘은 파라미터 이름보다는 객체의 필드 이름을 기반으로 바인딩이 이루어진다.
그래서 굳이 메서드 파라미터 이름이 없어도 동작에 큰 영향을 주지 않는다.
하지만 @RequestParam이나 @PathVariable처럼 개별 파라미터를 받을 경우에는 이름이 정말 중요하고, 그 이름이 런타임 시점에 없을 수도 있다는 사실을 반드시 인지해야 한다.
단순히 코드가 맞는 것처럼 보여도 컴파일러 레벨에서의 정보 손실이 애플리케이션 동작에 어떤 영향을 줄 수 있는지 체감할 수 있는 시간이었다.
'Backend > Spring Boot' 카테고리의 다른 글
API 예외처리: @ExceptionHandler (0) | 2025.05.21 |
---|---|
쿠키(Cookie)와 세션(Session) (1) | 2025.04.29 |
HTTP 응답 처리 방법의 발전 (0) | 2025.03.28 |
스프링 부트 계층형 아키텍처 (0) | 2025.03.27 |
빈이 존재하는 범위를 이해하자 (0) | 2025.02.19 |