React.js, 스프링 부트, AWS로 배우는 웹 개발 101

[TIL] 25/05/12, @PathVariable 사용시, java.lang.IllegalArgumentException 예외 발생

돌맹이떼굴떼굴 2025. 5. 13. 00:07

1.문제

@RestController
@RequestMapping("test")	// 리소스
public class TestController {

	// 매개변수를 넘겨받는 방법
	@GetMapping("/{id}")
	public String testControllerWithPathVariables(@PathVariable(required=false)int id) {
		return "Hello World! ID " + id;
	}

}

위와 같이 REST API Controller를 작성하고 요청을 보냈다. 요청은

 

1. http://localhost:8080/test/1234

2. http://localhost:8080/test

 

둘 다 보냈는데, 위는 500에러 아래는 404에러가 발생한다.

 

첫 번째, 부터 따져보면

2025-05-12T23:23:02.698+09:00 ERROR 8260 --- [demo] [nio-8080-exec-7] o.a.c.c.C.[.[.[/].[dispatcherServlet]    
: Servlet.service() for servlet [dispatcherServlet] in context with path [] threw exception [Request processing failed: 
java.lang.IllegalArgumentException: Name for argument of type [int] not specified, and parameter name information not available via reflection. Ensure that the compiler uses the '-parameters' flag.] with root cause

java.lang.IllegalArgumentException: Name for argument of type [int] not specified, and parameter name information not available via reflection. Ensure that the compiler uses the '-parameters' flag.

위와 같은 에러가 발생한다. 위 에러를 읽어보자면 int 타입의 인자의 이름이 분명치 않고, 파라미터의 정보를 사용할 수 없다는 말이다. 그리고, '-parameters' 플래그를 컴파일러에 사용하라고 알려준다.

 

이 에러는 Java 컴파일 시 파라미터 이름(id) 정보가 .class 파일에 포함되지 않아 발생한다. Spring은 @PathVariable("id")처럼 이름을 명시적으로 지정하지 않으면 리플렉션으로 파라미터 이름을 추론하는데, 컴파일 시 -parameters 옵션 없이 빌드하면 이 이름 정보가 JVM 메타데이터에 포함되지 않는다.

-> 너무 어려워서 우선 알고만 있어야 겠다ㅠ

 

public String testControllerWithPathVariables(@PathVariable("id") int id)

제일 빠른 방법은, id 명시적으로 써도 된다. 하지만 이것 저것 하다보니 답답해서 이클립스에서 인텔리제이로 넘어갔다.

 

두 번째, @PathVariable(required=false)를 쓰고 매개변수를 쓰지 않으면 에러가 발생하지 않는다고 책에 나와 있는데 404에러가 발생한다.

(required = false) 옵션은 이 매개변수가 필수가 아니라는 뜻으로, id=123을 명시하지 않아도 에러가 발생하지 않는다.

 

이유는 int에서 문제가 발생한다.

1. int는 기본형 -> null 불가능

2. @PathVariable(required = false)로 optional 설정해도 → 값이 없으면 null이 들어가야 함 → int에 null 할당 불가 → 예외 발생

 

// 매개변수를 넘겨받는 방법
@GetMapping({"/{id}", "/"})
public String testControllerWithPathVariables(@PathVariable(required=false)Integer id) {
    return "Hello World! ID " + id;
}

위와 같이 int가 아닌 Integer로 변경(Wrapper 클래스를 사용)하면

 

URL 경로에 값을 적지 않아도 에러가 발생하지 않고 null을 받을 수 있다.

 

@PathVariable(required = false)는 **"URL 경로가 정의된 경우 해당 값이 없어도 예외 안 나게 한다"**는 의미로 값이 없어도 예외 없이 출력할 수 있게 한다는 말이므로, 값 자체가 없을 때의 경로인 @GetMapping({"/{id}", "/"}) 둘 다 지정해야 한다.