- 아래와 같이 페이지 번호가 없는 경우와 있는 경우 2개의 URL 패턴을 지정했을 때, "/admin/items" URL 요청이 들어오면 @PathVariable("page")에 매핑되는 QueryString 변수가 없는데 어떻게 에러가 발생하지 않고 동작하는지에 대한 궁금증
Optional 객체 변수 ?
- page 의 자료형을 단순히 int형이 아닌 Optional<Integer> 를 사용한 것을 보아 Optional 객체로 변수를 지정하면 에러가 발생하지 않는 건가?? 라고 예상하여 page 의 자료형을 int형으로 바꾸고 테스트를 해봄
- "admin/items" URL 요청 결과 예상대로 이번에는 MissingPathVariableException 예외 발생
- 즉, 요청 URL 에 @PathVariable로 지정된 QueryString 변수가 없어도 Optional 객체 변수라면 에러가 발생하지 않고 정상적으로 동작한다. 이에 대한 사실은 Baeldung 사이트에서 확인할 수 있었다.
Optional Path Variable
기본적으로, 스프링은 URL 매핑 핸들러에서 @PathVariable 어노테이션이 지정된 파라미터와
요청 URL 패턴에서 해당 파라미터와 일치하는 변수를 바인드한다.
만약 일치하는 것을 찾을 수 없다면, Request를 해당 매핑 핸들러 메소드로 넘기지 않는다.
예들들어 URL 패턴에 id path 변수를 선택적으로 받는 getArticle 메소드가 있을때,
getArticle 메소드는 /article 과 /article/{id} URL 패턴을 모두 처리하게 되어있다.
만약 id path 변수가 존재한다면, 스프링은 ariticleId 변수에 그것을 바인딩할 것이다.
- URL 매핑 핸들러 메소드가 Path 변수가 없는 패턴, 있는 패턴을 모두 처리하도록 설정할 수 있음을 얘기함
예를들어, /article/123 URL 요청은 articeId 변수를 123 으로 초기화한다.
반대로, 만약 /article URL 요청을 보낸다면 스프링은 상태코드 500의 예외를 반환할 것이다.
왜냐면 {id} 부분이 없기 때문에 스프링이 articleId 파라미터에 값을 초기화할 수 없기 때문이다.
이러한 예외를 발생시키지 않기 위해서는 스프링에게 @PathVariable 파라미터 바인딩을 무시하도록 설정이 필요하다.
- 요청 URL에 @PathVariable 파라미터와 일치하는 QueryString 변수가 없으면 에러가 발생
스프링 4.3.3 이후부터는 @PathVariable 어노테이션에 boolean 속성인 "required" 를 통해서
핸들러 메소드에 path 변수가 필수적인지 아닌지를 선언할 수 있다.
required 속성이 false 이기 때문에 스프링은 요청 URL 안에 {id} path가 존재하지 않아도 에러를 발생시키지 않는다.
즉, 스프링은 {id} path 변수가 존재한다면 해당 값으로 articleId 를 초기화하고 그렇지 않으면 "null" 로 초기화한다.
반대로 required 속성의 값이 true라면 스프링은 원래대로 예외를 발생시킬것이다.
- 스프링 4.3.3 버전 이후부터는 @PathVariable 어노테이션에 required 속성을 통해 path 변수의 의무성을 제어할 수 있음
JDK 8 버전부터 지원되는 Optional 클래스를 사용하면 articleId 변수를 선택적으로 지정할 수 있다.
스프링은 id의 값을 유지하기 위해서 Optional<Integer> 타입의 optionalArticleId 변수를 생성한다.
만약 {id}가 존재한다면 그 값을 Optional 객체로 wrap 한다.
반대로 존재하지 않는다면 "null" 값으로 wrap 한다.
그러면 Optional 클래스의 isPresend(), get(), orElse() 메소드를 이용하여 해당 값에 접근할 수 있다.
- @PathVariable 어노테이션이 지정될 변수를 Optional 자료형으로 생성하면 Optional path 를 구현할 수 있다.
결론
- 요청 URL 패턴안에 @PathVariable 어노테이션이 지정된 파라미터와 일치하는 변수가 존재하지 않는다면 MissingPathVariableException 예외 발생
- @PathVariable 어노테이션에 required 속성값을 false로 설정하면 예외를 발생시키지 않음
- @PathVariable 어노테이션이 지정될 파라미터를 Optional 객체로 생성하면 예외를 발생시키지 않음