평소 ViewResolver에 전송할 문자열(경로)를 아무 생각없이 작성했었는데 실수로 작성한 코드가 작동되어 당황했던 기억이 있다. 왜 해당 부분이 가능한 지 확인해볼려고 한다.
해당 부분이 문제가 되는 부분이다. 얼핏 보면 이상한 점이 없지만 반환하는 경로를 확인할 필요가 있다.
items//createItemForm
Get 요청으로 상단의 URL 로 접속하면 위에 표시된 경로에 존재하는 HTML 파일을 반환한다.
그러나 현재 경로를 보면 슬래쉬가 2개이다! 하지만 문제없이 화면이 표시된다.
items/////////////createItemForm//////////////
더 의문인 점은 위 경로도 아무 문제없이 작동된다.
당연히 해당 경로는 처리되면 안되는 것 아닌가????
ModelAndView에 어떠한 파싱 과정 없이 문자열 그대로 저장되는 것을 확인할 수 있다. 실제로 이후 디버깅을 진행해 봤지만 해당 문자열의 중복 슬래쉬를 제거 한다던가 추가적인 작업을 하는 등의 행위는 Spring 에서 이뤄지지 않는다.
그렇다면 Spring이 아닌 다른 곳에서 이를 처리하는 부분이 분명히 존재할 것이다.
이곳 저곳 찾아보던 중 오늘도 Stackoverflow가 해결해줬다. 고마워요 Stackoverflow!!
In most cases, Win32 API functions will accept a wide range of variations in the path name format, including converting a relative path into an absolute path based on the current directory or per-drive current directory, interpreting a single dot as "this directory" and two dots as "the parent directory", converting forward slashes into backslashes, and removing extraneous backslashes and trailing periods.
So something like
c:\documents\..\code.\\working\.\myprogram\\\runme.exe..
will wind up interpreted as
c:\code\working\myprogram\runme.exe
정말 좋은 예시가 위에 나와 있는데 간단히 정리해보면 아래와 같다.
이와 같은 특징은 과거 UNIX 체제부터 Windows 까지 이어지는데 결국 Spring 이 처리하는게 아니라 File system에서 경로를 인식하고 처리한 것이다.
Getmapping 의 URI와 혼동하지 말자!!
앞서 설명한 경로가 인식되는 이유는 해당 문자열(경로)를 Spring이 그대로 반환하고 ViewResolver가 이를 File system에서 탐색하는 것이다. Getmapping 에서 탐색하는 것은 File 경로가 아닌 네트워크 URI이다. 당연히 다중 '/' 혹은 마침표를 추가한다면 에러가 발생하고 404 status를 반환할 것이다.
다중 '/'(슬래시)가 가능한 이유는 Spring container가 처리하는 게 아니라 File system이 이를 처리하기 때문!