정보

[Spring Boot] @PathVariable에 null이 들어올 때의 유효성 검사와 처리 방법 완전 정리

mindlab091904 2025. 5. 9. 16:34
반응형

Spring Boot 애플리케이션을 개발하다 보면 @PathVariable을 이용해 URL 경로에서 값을 추출하는 경우가 자주 있습니다. 하지만 이 값이 없거나(null) 들어오지 않을 경우, 즉 null 또는 비어 있는 상태로 요청이 들어온다면 어떻게 처리해야 할까요?

이번 포스팅에서는 Spring Boot 3.x 버전 기준(@SpringBootVersion 3.2.4) 으로 @PathVariable에 null이 들어오는 경우의 처리 방법을 상세히 살펴보고, 버전별 차이점, 실전 적용 코드, 그리고 권장되는 방식까지 모두 정리해 드립니다.


✅ 1. 기본적인 @PathVariable 사용법

먼저 @PathVariable은 URL 경로에서 값을 추출하는 데 사용됩니다.

@RestController
public class PathVariableController {

    @GetMapping("/path/{value}")
    public String getPathValue(@PathVariable(name = "value") String value) {
        return value;
    }
}

위 코드에서 /path/hello로 요청을 보내면, value에는 "hello"가 들어오고 그대로 반환됩니다.

🟡 만약 /path/로 요청하면?

이 경우 Spring Boot는 해당 요청에 대해 404 Not Found 응답을 보냅니다.
왜냐하면 @PathVariable은 필수 값이기 때문에 경로 자체가 매핑되지 않기 때문입니다.


✅ 2. @PathVariable(required = false)는 동작할까?

개발자들이 흔히 시도하는 방법 중 하나가 바로 아래와 같은 코드입니다.

@GetMapping("/path/optional/{value}")
public String optionalPathValue(@PathVariable(name = "value", required = false) String value) {
    return value == null ? "null" : value;
}

이론상으로는 required = false를 사용하면 null을 받을 수 있을 것처럼 보입니다.
하지만 실제로는 동작하지 않습니다.

❌ 왜 안 될까?

Spring Boot 3.2.4 (2024년 최신 버전) 및 이전의 Spring Boot 2.7.x에서도 @PathVariable(required = false)는 단독으로 동작하지 않습니다.
즉, 경로 변수가 빠져있으면 Controller 메서드 자체가 호출되지 않고, 여전히 404 오류를 발생시킵니다.

이는 @RequestParam과 달리 @PathVariable은 명시적인 경로 구조에 의존하기 때문입니다.


✅ 3. 올바른 해결 방법: 다중 매핑(Multi Mapping)

그렇다면 어떻게 해야 null 또는 비어있는 상태에서도 컨트롤러를 호출할 수 있을까요?

바로 다중 경로 매핑을 활용하는 것입니다.

@GetMapping({"/path/required-false", "/path/required-false/{value}"})
public String getPathVariableRequiredFalse(@PathVariable(name = "value", required = false) String value) {
    return value == null ? "Value is null" : value;
}

✅ 동작 원리

  • /path/required-false로 요청 → value는 null
  • /path/required-false/hello로 요청 → value는 "hello"

핵심 포인트는?

  • 두 개의 URI 경로를 각각 매핑한다는 점입니다.
  • 하나는 value가 없는 기본 경로, 다른 하나는 value가 있는 경로입니다.

이 방식은 Spring Boot 2.7.x와 3.x 모두에서 완벽하게 동작합니다.


✅ 4. 실전 팁: Optional을 활용한 방법

자바의 Optional 클래스를 활용하면 더욱 깔끔한 코드 작성이 가능합니다.

@GetMapping({"/path/optional", "/path/optional/{value}"})
public String getOptionalPathValue(@PathVariable(name = "value", required = false) Optional<String> value) {
    return value.orElse("No value provided");
}

✅ 장점

  • null 체크 필요 없음
  • 의도를 명확하게 표현
  • 실무에서 클린 코드 유지에 효과적

✅ 5. 다른 방법: DefaultValue 활용 (단, 권장되진 않음)

간혹 @RequestParam처럼 default 값을 설정하고 싶다는 질문이 있습니다.
하지만 @PathVariable에는 defaultValue 옵션이 없습니다.

// 잘못된 예시: defaultValue는 @RequestParam에만 존재
@GetMapping("/path/{value}")
public String getPathDefault(@PathVariable(name = "value", defaultValue = "default") String value) {
    return value;
}

이 코드는 컴파일 에러가 발생합니다.

🛑 결론: @PathVariable에는 defaultValue 사용 불가!


✅ 6. 예외 처리 적용 예시 (선택 사항)

경로 변수의 유효성을 검사하고, null 혹은 빈 문자열이 들어왔을 때 별도로 처리하고 싶다면 @ControllerAdvice를 통해 예외를 잡을 수도 있습니다.

@ControllerAdvice
public class GlobalExceptionHandler {

    @ExceptionHandler(MissingPathVariableException.class)
    public ResponseEntity<String> handleMissingPathVariable(MissingPathVariableException ex) {
        return ResponseEntity.status(HttpStatus.BAD_REQUEST).body("Path variable is missing!");
    }
}

하지만 이는 주로 복잡한 프로젝트나 API 통합 레이어에서 사용되며,
일반적인 null 허용 시에는 앞서 소개한 다중 매핑 방식이 가장 효율적입니다.


🔍 7. 정리: @PathVariable null 값 처리 핵심 요약

구분 동작 여부 설명

@PathVariable(required = false) 경로 누락 시 404 발생
다중 경로 매핑 {"/path", "/path/{value}"} null 허용 가능
Optional<String> 사용 null 체크 없이 안전하게 사용 가능
defaultValue 옵션 사용 @RequestParam에서만 가능

✍️ 마무리하며

@PathVariable은 매우 자주 쓰이지만, 그 동작 방식에 대한 오해도 많은 애너테이션입니다.
Spring Boot 3.x 환경에서는 required = false만으로는 null 처리가 되지 않으므로 반드시 다중 경로 매핑을 활용해야 합니다.

정확한 버전별 동작 차이를 이해하고, Optional, 다중 매핑, 예외 처리 등 다양한 기법을 적절히 조합하여 안정적인 API 엔드포인트를 구축해보세요.

 

반응형