You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
재홍님의 #1 이슈에 대한 답변 이슈이자, 공유하고 싶은 내용이어서 조금 길지만 작성해봅니다!
(스크린샷이 잘 보이지 않아서 화면을 확대해서 보길 권장합니다!)
😁 공유하고 싶은 내용
테스트용 Controller
존재하지 않는 viewName을 반환한다.
DispatcherServlet은 가장먼저 “/”로 들어온 요청에 대해 처리를 시작합니다. 이때 요청 URI는 “/”가 되고, DispatcherType은 “REQUEST”가 됩니다.
TestController의 test()메소드가 해당 URI와 매핑되어있으므로 해당 컨트롤러를 실행하고 반환값으로 “dd”라는 viewName을 받게 됩니다.
해당 정보를 가지고 ModelAndView를 생성하고 내부 View 정보를 통해 RequestDispatcher가 forwarding 작업을 합니다.
포워딩 됐으므로 dispatcherType은 FORWARD이며, “/dd” 라는 리소스를 DispatcherServlet이 내부적으로 호출하게 됩니다.
다시 DispatcherServlet을 통해 내부적인 doService() → doDispatch 작업을 수행하게 됩니다.
DispatcherServlet.doDispatch()에서 HandlerAdapter를 찾아 handle()하게 되는데 이는 어댑터(HttpRequestHandlerAdapter)를 통해 찾아온 핸들러를 실행시키게 됩니다.
이때 정적 리소스를 처리하는 ResourceHttpRequestHandler가 선택되고 “/dd”에 대한 실제 리소스를 가져오지만 존재하지 않으므로 null값이 반환됩니다.
resource가 null이므로 Not Found 에러를 Response 객체에 세팅합니다. 이때 sendError내부 코드에서 setError를 통해 0 → 1로 에러 플래그를 세팅합니다.
사용자의 “/” 요청이 마무리되고 WAS까지 404 Error가 전파됩니다. 그리고 Tomcat에서 에러가 존재하는지 묻게 됩니다.
이때 아까 setError를 통해 1로 세팅한 에러값을 통해 에러가 있음을 WAS가 인지하게 됩니다.
이후 404 Not Found에 대한 에러 페이지를 찾게 됩니다. 따로 생성한 에러페이지는 존재하지 않으므로 WAS에서 생성하는 디폴트 에러 페이지를 찾게 됩니다.
/error 로케이션을 받아오고 이후 각종 에러에 대한 세팅을 해줍니다(DispatcherType을 ERROR 세팅 등)
이후 /error에 대해 WAS 내부에서 포워딩 작업을 실행합니다.
포워딩 작업이 시작됐으므로 다시 필터를 거치고 DispatcherServlet을 호출하게 됩니다.
“/error”로 requestURI가 선택되어 있는데 해당 uri는 BasicErrorController의 @RequestMapping과 일치합니다.
또한 Accept header가 text/html이므로 BasicErrorController#errorHtml 핸들러 메소드가 선택됩니다. RequestMappingHandlerAdapter는 이런 @RequestMapping이 되어있는 핸들러를 지원하므로(HandlerAdapter#supports를 지원함) 어댑터로 선택됩니다.
(이 이미지는 좌측 하단의 main 쓰레드내 메소드 스택을 통해 흐름을 이해하기 편하도록 첨부했습니다.)
이후 실제 BasicErrorController#errorHtml을 실행한다.
errorHtml의 내부 호출 메소드인 resolveErrorView에서는DefaultErrorViewResolver#resolveErrorView를 호출해 에러페이지에 대한 view resolving 수행합니다.
DefaultErrorViewResolver#resoveErrorView 에서는 두번째 사진의 staticLocations과 같은 순서로 view를 찾는다.
하지만 일치하는 View가 없으므로 null을 반환하게 된다. BasicErrrorController#errorHtml에서는 반환된 ModelAndView 객체가 null값이라면 “error”라는 viewName을 가진 ModelAndView 객체를 생성해 반환한다.
반환된 ModelAndView 객체를 처리하가 위해 ModelAndView 응답 value를 처리하는 핸들러로 ModelAndViewMethodReturnValueHandler가 선택된다.
이곳에서 뷰 이름 세팅, 응답 코드 세팅 , 리다이렉트에 대한 처리 등을 수행한다.
이후 BasicErrorController#errorHtml을 통해 생성된 ModelAndView 객체가 DispatcherServlet으로 반환된다.
받아온 ModelAndView 객체 내부의 View를 reolving하는데 이때 ContentNegotiatingViewReolver가 선택된다.
ContentNegotiatingViewResolver#resolveViewName 에서는 getCandiateViews()를 통해 후보가 될 수 있는 View를 선택하고 이후 getBestView()를 통해 최적의 View를 선택한다.
후보군 View로는 ErrorMvcAutoConfiguration$StaticView와 정적 리소스를 처리하는 InternalResourceView 2개가 선택된다.
best view로는 ErrorMvcAutoConfiguration$StaticView가 더 높은 우선순위를 가지고 있고, text/html에 대해 ErrorMvcAutoConfiguration$StaticView가 처리할 수 있으므로 즉시 해당 뷰를 반환한다.
이후 DispatcherServlet은 받아온 ErrorMvcAutoConfiguration$StaticView를 통해 뷰 렌더링을 진행한다.
실제 StaticView의 render 메소드를 살펴보면 우리가 익히 볼 수 있는 Whitelabel Error Page를 볼 수 있다. 여기서 이전에 정해진 error 내용과 status code를 결합해 응답 HTML을 완성한다.
이후 응답 처리를 마치고 브라우저에는 404 Whitelabel Error Page가 응답된다.
📌 참고자료
Springframwork 내부 코드
The text was updated successfully, but these errors were encountered:
🤔 왜 이슈를 생성했나요?
재홍님의 #1 이슈에 대한 답변 이슈이자, 공유하고 싶은 내용이어서 조금 길지만 작성해봅니다!
(스크린샷이 잘 보이지 않아서 화면을 확대해서 보길 권장합니다!)
😁 공유하고 싶은 내용
테스트용 Controller
존재하지 않는 viewName을 반환한다.
DispatcherServlet은 가장먼저 “/”로 들어온 요청에 대해 처리를 시작합니다. 이때 요청 URI는 “/”가 되고, DispatcherType은 “REQUEST”가 됩니다.
TestController의 test()메소드가 해당 URI와 매핑되어있으므로 해당 컨트롤러를 실행하고 반환값으로 “dd”라는 viewName을 받게 됩니다.
해당 정보를 가지고 ModelAndView를 생성하고 내부 View 정보를 통해 RequestDispatcher가 forwarding 작업을 합니다.
포워딩 됐으므로 dispatcherType은 FORWARD이며,
“/dd”
라는 리소스를 DispatcherServlet이 내부적으로 호출하게 됩니다.다시 DispatcherServlet을 통해 내부적인 doService() → doDispatch 작업을 수행하게 됩니다.
DispatcherServlet.doDispatch()에서 HandlerAdapter를 찾아 handle()하게 되는데 이는 어댑터(HttpRequestHandlerAdapter)를 통해 찾아온 핸들러를 실행시키게 됩니다.
이때 정적 리소스를 처리하는
ResourceHttpRequestHandler
가 선택되고 “/dd”에 대한 실제 리소스를 가져오지만 존재하지 않으므로 null값이 반환됩니다.resource가 null이므로 Not Found 에러를 Response 객체에 세팅합니다. 이때 sendError내부 코드에서 setError를 통해 0 → 1로 에러 플래그를 세팅합니다.
사용자의 “/” 요청이 마무리되고 WAS까지 404 Error가 전파됩니다. 그리고 Tomcat에서 에러가 존재하는지 묻게 됩니다.
이때 아까 setError를 통해 1로 세팅한 에러값을 통해 에러가 있음을 WAS가 인지하게 됩니다.
이후 404 Not Found에 대한 에러 페이지를 찾게 됩니다. 따로 생성한 에러페이지는 존재하지 않으므로 WAS에서 생성하는 디폴트 에러 페이지를 찾게 됩니다.
/error
로케이션을 받아오고 이후 각종 에러에 대한 세팅을 해줍니다(DispatcherType을 ERROR 세팅 등)이후
/error
에 대해 WAS 내부에서 포워딩 작업을 실행합니다.포워딩 작업이 시작됐으므로 다시 필터를 거치고 DispatcherServlet을 호출하게 됩니다.
“/error”로 requestURI가 선택되어 있는데 해당 uri는
BasicErrorController
의 @RequestMapping과 일치합니다.또한
Accept header
가text/html
이므로BasicErrorController#errorHtml
핸들러 메소드가 선택됩니다.RequestMappingHandlerAdapter
는 이런@RequestMapping
이 되어있는 핸들러를 지원하므로(HandlerAdapter#supports
를 지원함) 어댑터로 선택됩니다.(이 이미지는 좌측 하단의 main 쓰레드내 메소드 스택을 통해 흐름을 이해하기 편하도록 첨부했습니다.)
이후 실제
BasicErrorController#errorHtml
을 실행한다.errorHtml의 내부 호출 메소드인 resolveErrorView에서는DefaultErrorViewResolver#resolveErrorView를 호출해 에러페이지에 대한 view resolving 수행합니다.
DefaultErrorViewResolver#resoveErrorView
에서는 두번째 사진의staticLocations
과 같은 순서로 view를 찾는다.하지만 일치하는 View가 없으므로 null을 반환하게 된다.
BasicErrrorController#errorHtml
에서는 반환된 ModelAndView 객체가 null값이라면“error”
라는viewName
을 가진 ModelAndView 객체를 생성해 반환한다.반환된 ModelAndView 객체를 처리하가 위해 ModelAndView 응답 value를 처리하는 핸들러로 ModelAndViewMethodReturnValueHandler가 선택된다.
이곳에서 뷰 이름 세팅, 응답 코드 세팅 , 리다이렉트에 대한 처리 등을 수행한다.
이후
BasicErrorController#errorHtml
을 통해 생성된 ModelAndView 객체가 DispatcherServlet으로 반환된다.받아온 ModelAndView 객체 내부의 View를 reolving하는데 이때
ContentNegotiatingViewReolver
가 선택된다.ContentNegotiatingViewResolver#resolveViewName
에서는getCandiateViews()
를 통해 후보가 될 수 있는 View를 선택하고 이후getBestView()
를 통해 최적의 View를 선택한다.후보군 View로는
ErrorMvcAutoConfiguration$StaticView
와 정적 리소스를 처리하는InternalResourceView
2개가 선택된다.best view로는 ErrorMvcAutoConfiguration$StaticView가 더 높은 우선순위를 가지고 있고, text/html에 대해 ErrorMvcAutoConfiguration$StaticView가 처리할 수 있으므로 즉시 해당 뷰를 반환한다.
이후 DispatcherServlet은 받아온 ErrorMvcAutoConfiguration$StaticView를 통해 뷰 렌더링을 진행한다.
실제 StaticView의 render 메소드를 살펴보면 우리가 익히 볼 수 있는
Whitelabel Error Page
를 볼 수 있다. 여기서 이전에 정해진 error 내용과 status code를 결합해 응답 HTML을 완성한다.이후 응답 처리를 마치고 브라우저에는 404 Whitelabel Error Page가 응답된다.
📌 참고자료
The text was updated successfully, but these errors were encountered: